样例不过求助
查看原帖
样例不过求助
1191031
majingxuan123楼主2024/8/5 18:18
#include<iostream>
using namespace std;
const int maxn=(1<<16);
int r[16],c[16],w[4][4],p[maxn],f[maxn];
        int lowbit(int x){return x&(-x);}
        int get(int x,int y){return r[x]&c[y]&w[x/4][y/4];}
void init(){
	for(int i=0;i<maxn;i++){
		for(int j=i;j;j-=lowbit(j))p[i]++;
	}
	for(int i=0;i<16;i++)f[1<<i]=i; 
}
void clear(){
	for(int i=0;i<16;i++)c[i]=r[i]=maxn-1;
	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++)w[i][j]=maxn-1;
	}
}
char s[16][16];
bool dfs(int num){
	if(num==0)return true;
	//空格 
	for(int i=0;i<16;i++){
		for(int j=0;j<16;j++){
			if(s[i][j]=='-'){
				int x=get(i,j);
				if(p[x]==0)return false;
				if(p[x]==1){
					int k=f[lowbit(x)];
					r[i]&=(~(1<<k)),c[j]&=(~(1<<k)),w[i/4][j/4]&=(~(1<<k)),s[i][j]=k+'A';
					if(dfs(num-1))return true;
					r[i]|=(1<<k),c[j]|=(1<<k),w[i/4][j/4]|=(1<<k),s[i][j]='-';
					return false;
				}
			}
		}
	}
	//行 
	for(int i=0;i<16;i++){
		int res=0;
		int cnt[16]={0};
		for(int j=0;j<16;j++){
			if(s[i][j]=='-'){
				int x=get(i,j);
				res|=x;
				for(int k=x;k;k-=lowbit(k))cnt[f[lowbit(k)]]++;
			}
			else{
				res|=(1<<(s[i][j]-'A'));
				cnt[s[i][j]-'A']=-16;
			}
		}
		if(res<maxn-1)return false;
		for(int k=0;k<16;k++){
			if(cnt[k]!=1)continue;
			for(int j=0;j<16;j++){
				int x=get(i,j);
				if(s[i][j]=='-'&&((x>>k)&1)){
					r[i]&=(~(1<<k)),c[j]&=(~(1<<k)),w[i/4][j/4]&=(~(1<<k)),s[i][j]=k+'A';
					if(dfs(num-1))return true;
					r[i]|=(1<<k),c[j]|=(1<<k),w[i/4][j/4]|=(1<<k),s[i][j]='-';
					return false;
				}
			}
		}
	}
	//列
	for(int j=0;j<16;j++){
		int res=0;
		int cnt[16]={0};
		for(int i=0;i<16;i++){
			if(s[i][j]=='-'){
				int x=get(i,j);
				res|=x;
				for(int k=x;k;k-=lowbit(k))cnt[f[lowbit(k)]]++;
			}
			else{
				res|=(1<<(s[i][j]-'A'));
				cnt[s[i][j]-'A']=-16;
			}
		}
		if(res<maxn-1)return false;
		for(int k=0;k<16;k++){
			if(cnt[k]!=1)continue;
			for(int i=0;i<16;i++){
				int x=get(i,j);
				if(s[i][j]=='-'&&((x>>k)&1)){
					r[i]&=(~(1<<k)),c[j]&=(~(1<<k)),w[i/4][j/4]&=(~(1<<k)),s[i][j]=k+'A';
					if(dfs(num-1))return true;
					r[i]|=(1<<k),c[j]|=(1<<k),w[i/4][j/4]|=(1<<k),s[i][j]='-';
					return false;
				}
			}
		}
	}
	//16宫格 
	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++){
			int res=0;
			int cnt[16]={0};
			for(int x=i*4;x<=i*4+3;x++){
				for(int y=j*4;y<=j*4+3;y++){
					if(s[x][y]=='-'){
						int n=get(x,y);
						res|=n;
						for(int k=n;k;k-=lowbit(k))cnt[f[lowbit(k)]]++;
					}
					else{
						res|=(1<<(s[x][y]-'A'));
						cnt[s[x][y]-'A']=-16;
					}
				}
			}
			if(res<maxn-1)return false;
			for(int k=0;k<16;k++){
				if(cnt[k]!=1)continue;
				for(int x=i*4;x<=i*4+3;x++){
					for(int y=j*4;y<=j*4+3;y++){
						int n=get(x,y);
						if(s[x][y]=='-'&&((n>>k)&1)){
							r[x]&=(~(1<<k)),c[y]&=(~(1<<k)),w[x/4][y/4]&=(~(1<<k)),s[x][y]=k+'A';
							if(dfs(num-1))return true;
							r[x]|=(1<<k),c[y]|=(1<<k),w[x/4][y/4]|=(1<<k),s[x][y]='-';
							return false;
						}
					}
				}
			}
		}
	}
	int t=16,x,y;
	for(int i=0;i<16;i++){
		for(int j=0;j<16;j++){
			if(s[i][j]=='-'){
				int tmp=get(i,j);
				if(tmp<t)t=tmp,x=i,y=j;
			}
		}
	}
	for(int i=get(x,y);i;i-=lowbit(i)){
		int k=f[lowbit(i)];
		r[x]&=(~(1<<k)),c[y]&=(~(1<<k)),w[x/4][y/4]&=(~(1<<k)),s[x][y]=k+'A';
		if(dfs(num-1))return true;
		r[x]|=(1<<k),c[y]|=(1<<k),w[x/4][y/4]|=(1<<k),s[x][y]='-';
	}
	return false;
}
int main(){
	init(); 
	while(scanf("%s",s[0])==1){
		clear();
		for(int i=1;i<16;i++)scanf("%s",s[i]);
		int num=0;
		for(int i=0;i<16;i++){
			for(int j=0;j<16;j++){
				if(s[i][j]=='-')num++;
				else{
					int k=s[i][j]-'A';
					r[i]&=(~(1<<k));
					c[i]&=(~(1<<k));
					w[i/4][j/4]&=(~(1<<k));
				}
			}
		} 
		dfs(num);
		for(int i=0;i<16;i++){
			for(int j=0;j<16;j++){
				printf("%c",s[i][j]);
			}
			printf("\n");
		}
		printf("\n");
	}
	return 0;
}
2024/8/5 18:18
加载中...