https://www.luogu.com.cn/problem/P1162
先给出我潦草的代码
#include<bits/stdc++.h>
using namespace std;
int n;
int Map[50][50];
bool judge1(int x,int y){
if(Map[x-1][y]!=0&&Map[x][y-1]!=0&&Map[x-1][y-1]!=0){
return true;
}
else return false;
}
bool judge2(int x,int y){
if(Map[x+1][y]!=0&&Map[x][y+1]!=0&&Map[x+1][y+1]!=0){
return true;
}
else return false;
}
void solve(){
bool flag=false;
//从左上角一圈一圈地查找;一号循环
for (int i = 2; i <= n-1; ++i) {
for (int j = 2; j <= i; ++j) {
if (judge1(i,j)&&Map[i][j]!=1){
Map[i][j]=2;
}
if (judge1(j,i)&&Map[j][i]!=1){
Map[j][i]=2;
}
}
}
//将上一个循环的漏洞(右下角会产生错误的2)堵上;二号循环
for (int i = n-1; i >= 2; i--) {
for (int j = n-1; j >= i; --j) {
if (!judge2(i,j)&&Map[i][j]==2){
Map[i][j]=0;
}
if (!judge2(j,i)&&Map[j][i]==2){
Map[j][i]=0;
}
}
}
}
int main() {
cin>>n;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
cin>>Map[i][j];
}
}
solve();
for (int i = 1; i <= n; ++i) {
for (int j = 1; j < n; ++j) {
cout<<Map[i][j]<<' ';
}
if (i<n){
cout<<Map[i][n]<<endl;
}
else cout<<Map[i][n];
}
return 0;
}
这里我的想法是
从圈的左上角开始找,故有一个非圈边上的点(x,y),这里的,只要满足(x-1,y)(x,y-1)(x-1,y-1)这三个点非零的,就可证明(x,y)必定在圈内。
当然这个算法有漏洞,就是当右下角出现
会使上诉条件在圈外的地方成立
但也因为如此,我们可以发现上诉条件是有对称性的,因此我们只需从右下角开始倒着找出现错误的点然后修正即可。
因此有了循环二;
这样问题便解决了。