题解 CF442A 【Borya and Hanabi】

一道细节题

因为英文和数字很少,所以就枚举要提醒的字母和数字,验证是否可以算出来然后再更新答案。

可以推出来的有以下几种:

  • 已知颜色,数字未知的只剩下一个

  • 已知数字,颜色未知的只剩下一个

  • 最后剩下一个

代码

#include
#include
using namespace std;
int n,a[6][6],k1[6],tot1,k2[6],tot2,ans=25,v[6][6];
char c[3];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",c);
		a[(c[0]=='R'?1:(c[0]=='G'?2:(c[0]=='B'?3:(c[0]=='W'?4:5))))][c[1]-'0']=1;
	}
	for(int i=0;i<(1<<5);i++){
		tot1=0;memset(k1,0,sizeof(k1));
		for(int k=0;k<5;k++)if(i>>k&1)tot1++,k1[k+1]=1;
		for(int j=0;j<(1<<5);j++){
			tot2=0;memset(k2,0,sizeof(k2));
			for(int k=0;k<5;k++)if(j>>k&1)tot2++,k2[k+1]=1;
			if(tot1+tot2>=ans)continue;
			memset(v,0,sizeof(v));
			for(int k=1;k<=5;k++)for(int l=1;l<=5;l++)if(a[k][l]&&k1[k]&&k2[l])v[k][l]=1;
			while(1){
				int t=0;
				for(int k=1;k<=5;k++){
					if(!k1[k])continue;
					int tot=0,p=0;
					for(int l=1;l<=5;l++)if(a[k][l]&&!v[k][l])tot++,p=l;
					if(tot==1)v[k][p]=1,t++;
				}
				for(int k=1;k<=5;k++){
					if(!k2[k])continue;
					int tot=0,p=0;
					for(int l=1;l<=5;l++)if(a[l][k]&&!v[l][k])tot++,p=l;
					if(tot==1)v[p][k]=1,t++;
				}
				if(!t)break;
			}
			int t=0;
			for(int k=1;k<=5;k++)for(int l=1;l<=5;l++)if(a[k][l]&&!v[k][l])t++;
			if(t<=1)ans=tot1+tot2;
		}
	}
	printf("%d",ans);
	return 0;
}

你可能感兴趣的:(题解 CF442A 【Borya and Hanabi】)