141 丝雨姐的入门day1枚举贪心 A题 递归暴搜

POJ 1753

要求:4*4的黑白棋盘,w代表白色棋子,b代表黑色棋子,每次改变一个棋子的颜色,它周围紧邻的所有棋子均变色。

方法:递归暴搜。

1.预处理白色为0,黑色为1。

2.每个棋子只能翻0次或1次,每翻两次和不翻一样,翻0个棋子,翻1个棋子,...,翻16个棋子,共2^16次方种方案。

3.因数据过小,可直接递归暴搜,用生成16位二进制数的方法决定取棋子的策略。

4.每种方案进行判定,若和为0或65535(全0和全1),则符合要求。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[20],num[20],temp[20],ans=17;
int two[16]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,
8192,16384,32768};
void judge()
{
 int i,j,cnt=0,sum=0;
 memcpy(temp,num,sizeof(num));
 for(i=0;i<16;i++)
 {
  if(a[i])
  {
   cnt++;
   temp[i]=1-temp[i];
   if(i-4>=0) temp[i-4]=1-temp[i-4];
   if(i+4<16) temp[i+4]=1-temp[i+4];
   if(i%4!=0) temp[i-1]=1-temp[i-1];
   if(i%4!=3) temp[i+1]=1-temp[i+1];
  }	
 }
 for(i=0;i<16;i++)
 {
  if(temp[i])
  {
   sum+=two[i];
  }	
 }		
 if(sum==0||sum==65535) ans=min(ans,cnt);
}
void dfs(int n)
{
 int i;
 if(n==16)
 {
 	judge();
 	return;
 }
 for(i=0;i<2;i++)
 {
  a[n]=i;
  dfs(n+1);	
 }
}
int main()
{
 int i,j,t;
 char s[20];
 for(i=0;i<4;i++)
 {
  scanf("%s",&s);
  for(j=0;j<4;j++)
  {
  if(s[j]=='b') num[i*4+j]=1;
  else num[i*4+j]=0;
  }
 }
 dfs(0);
 if(ans<=16) printf("%d\n",ans);
 else printf("Impossible\n");
}

猜你喜欢

转载自blog.csdn.net/Irving0323/article/details/81670989