题解:P10419 [蓝桥杯 2023 国 A] 01 游戏

本题是一道搜索+模拟。

  1. 考虑每行每列的情况是可以通过hash来判断,因为 \(n\le10\) 并且为 \(01\) 串容易想到转为二进制,且不会自然溢出。
  2. 接下来考虑每行每列 \(0\)\(1\) 的个数,比较快捷的方法是统计 \(0\)\(1\) 的数量有没有超过 \(n\div2\)
  3. 考虑调试方便以及代码整洁,推荐上述操作写成一个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;
}

做这类题需要必不可少的耐心与细心,希望我们能沉下心,认认真真的去完成每道题。

愉快结束。

posted @ 2025-02-08 13:12  Tighnari  阅读(50)  评论(0)    收藏  举报