专栏文章
题解:CF1567F One-Four Overload
CF1567F题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mio0j6wh
- 此快照首次捕获于
- 2025/12/02 11:22 3 个月前
- 此快照最后确认于
- 2025/12/02 11:22 3 个月前
提供一种比较好写的直接构造的方法。
提示
以下为笔者的思考过程,可以跳过直接看最后的构造部分。
容易想到先确定非标记点,限制每个标记点周围和为 的倍数,这等价于在此邻域中对于每个 存在不同且唯一的 与其对应。注意到每个标记点四相邻标记点数为偶数,否则显然无解,于是标记点构成若干个欧拉回路,即若干可自交的多边形。
发现多边形内外可以分开考虑,且内部问题形式类似。请注意这里的内外是广义的,因为多边形有自交,可以通过光线投射算法判断其内外,即某一方向到边界前经过边数的奇偶性,注意边界情况。
由于对于多边形内部只有角块,所以只要考虑拐角格不同的限制,显然只要按行奇偶性赋值即可。特别的,多边形为空仍成立。
对于多边形内外间,只有边块的限制,只要给内部全部取反即可。
总结一下,对于每个位置的赋值,只要求出其行编号奇偶性和是否在多边形内部的异或和,对应赋 或 ,正确性显然。
CPP#include<bits/stdc++.h>
using namespace std;
int n,m,a[505][505],ans[505][505];
char c[505][505];
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin>>n>>m;
for(int i=0;i<n;i++) cin>>c[i];
for(int i=1;i<n-1;i++){
int cur=0,lst=0;
for(int j=m-1;j>=0;j--){
if(j&&j<m-1&&c[i][j]=='X'&&((c[i-1][j]=='.')+(c[i+1][j]=='.')+(c[i][j-1]=='.')+(c[i][j+1]=='.'))&1) return cout<<"NO\n",0;
if(c[i][j]=='X'&&c[i-1][j]=='X'&&c[i+1][j]=='X'){
cur^=1;
continue;
}
if(c[i][j]=='X'&&c[i-1][j]=='X'){
if(lst) cur^=(lst==1),lst=0;
else lst=-1;
continue;
}
if(c[i][j]=='X'&&c[i+1][j]=='X'){
if(lst) cur^=(lst==-1),lst=0;
else lst=1;
continue;
}
if(c[i][j]!='X') ans[i][j]=cur;
}
}
cout<<"YES\n";
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(c[i][j]!='X') cout<<((ans[i][j]^(i&1)?1:4))<<' ';
else cout<<((c[i-1][j]=='.')+(c[i+1][j]=='.')+(c[i][j-1]=='.')+(c[i][j+1]=='.')>>1)*5<<' ';
}
cout<<'\n';
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...