题解:P10419 [蓝桥杯 2023 国 A] 01 游戏
本题是一道搜索+模拟。
- 考虑每行每列的情况是可以通过hash来判断,因为 \(n\le10\) 并且为 \(01\) 串容易想到转为二进制,且不会自然溢出。
- 接下来考虑每行每列 \(0\) 和 \(1\) 的个数,比较快捷的方法是统计 \(0\) 或 \(1\) 的数量有没有超过 \(n\div2\)。
- 考虑调试方便以及代码整洁,推荐上述操作写成一个check函数,详细见如下代码。
AC code:
#include<iostream>
#include<map>
#include<cstring>
#include<cmath>
using namespace std;
int n;
char a[15][15];
bool ha1[2050],ha2[2050];
int sx,sy,cnt;
int hash1(int x) {
int res=0;
for(int i=n; i>=1; i--) {
res+=(a[x][i]-'0')*pow(2,n-i);
}
return res;
}
int hash2(int y) {
int res=0;
for(int i=1; i<=n; i++) {
res+=(a[i][y]-'0')*pow(2,i-1);
}
return res;
}
bool check(int x,int y,char co) {
a[x][y]=co;
int sum=0;
for(int i=x+1; i<=n; i++) {
if(a[i][y]==co) sum++;
else break;
}
for(int i=x-1; i>=1; i--) {
if(a[i][y]==co) sum++;
else break;
}
if(sum>1) return false;
sum=0;
for(int i=y+1; i<=n; i++) {
if(a[x][i]==co) sum++;
else break;
}
for(int i=y-1; i>=1; i--) {
if(a[x][i]==co) sum++;
else break;
}
if(sum>1) return false;
sum=0;
int sum0=0,sum1=0;
for(int i=1; i<=n; i++) {
if(a[i][y]=='0') sum0++;
if(a[i][y]=='1') sum1++;
}
if(sum0>n/2 || sum1>n/2) return false;
sum0=0,sum1=0;
for(int i=1; i<=n; i++) {
if(a[x][i]=='0') sum0++;
if(a[x][i]=='1') sum1++;
}
if(sum0>n/2 || sum1>n/2) return false;
return true;
}
void print() {
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
cout<<a[i][j];
}
cout<<endl;
}
return;
}
void dfs(int x,int y,int cnt) {
// cout<<x<<' '<<y<<' '<<cnt<<endl;
// print();
if(cnt==n*n) {
for(int i=1; i<=n; i++) {
int d1=hash1(i);
int d2=hash2(i);
if(ha1[d1] || ha2[d2]){
for(int k=1;k<=1025;k++){
ha1[k]=0;ha2[k]=0;
}
return;
}
else{
ha1[d1]=1;
ha2[d2]=1;
}
}
print();
exit(0);
}
if(a[x][y]=='_') {
if(check(x,y,'0')) {
a[x][y]='0';
if(y<n) {
dfs(x,y+1,cnt+1);
a[x][y]='_';
} else if(y==n) {
dfs(x+1,1,cnt+1);
a[x][y]='_';
}
}
if(check(x,y,'1')) {
a[x][y]='1';
if(y<n) {
dfs(x,y+1,cnt+1);
a[x][y]='_';
} else {
dfs(x+1,1,cnt+1);
a[x][y]='_';
}
}
a[x][y]='_';
} else {
if(y<n) {
dfs(x,y+1,cnt);
} else {
dfs(x+1,1,cnt);
}
}
return;
}
int main() {
cin>>n;
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
cin>>a[i][j];
if(a[i][j]!='_') cnt++;
}
}
dfs(1,1,cnt);
return 0;
}
做这类题需要必不可少的耐心与细心,希望我们能沉下心,认认真真的去完成每道题。
愉快结束。

浙公网安备 33010602011771号