您的位置:首页 > 大数据 > 人工智能

POJ 1681 Painter's Problem(开关问题)

2017-08-03 10:08 435 查看
开关问题的解法:把第一行的数开或关有2^n次方种可能00000-11111.遍历这么多种可能,给第一行赋值,第二行考虑让自己能影响到的第一行的数成立,第三行考虑让自己能影响到的第二行的数成立……最后判断一下是否所有的数都能成立。复杂度为(n*n*2^n)所以n必须是一个小的值

#include "cstdio"
#include "iostream"
#include "cstring"
using namespace std;
bool wall[18][18];
bool paint[18][18];
int count1,n;
bool allyellow()
{
count1=0;
for(int i=1; i<=n; i++)
{for(int j=1; j<=n; j++)
{
if(wall[i][j]^paint[i][j]^paint[i][j-1]^paint[i][j+1]^paint[i-1][j]^paint[i+1][j])
return false;
if(paint[i][j]==1)count1++;
}
}

return true;
}
int main()
{
int t;
char c;
scanf("%d",&t);
while(t--)
{
memset(wall,0,sizeof(wall));
scanf("%d%*c",&n);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
scanf("%c",&c);
if(c=='w')wall[i][j]=1;
}
getchar();
}
int maxn=1<<n;
int min1=1000;
for(int i=0; i<maxn; i++)
{
memset(paint,0,sizeof(paint));
int tmp=i;
for(int j=1; j<=n; j++)
{
paint[1][j]=tmp&1;
tmp/=2;
}
for(int k=2; k<=n; k++)
{
for(int p=1; p<=n; p++)
{
if(wall[k-1][p]^paint[k-1][p]^paint[k-1][p-1]^paint[k-1][p+1]^paint[k-2][p])
paint[k][p]=true;
}
}

if(allyellow()==true)
{
min1=min(min1,count1);
}
}
if(min1==1000)printf("inf\n");
else printf("%d\n",min1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: