pku 1753 Flip Game 第一周训练 ——枚举

http://poj.org/problem?id=1753

以前做过的一道题目,可是拿过来在做就没思路了。还是看了以前做的。唉。。悲剧啊。。

思路:首先将整个4*4的棋盘,压缩到一个一维数组中,然后对每一个点的两种状态(翻转或者不翻转)枚举。枚举完所有的情况,最后查看是否能够达到目标。

 

View Code
#include <cstdio>
#include <cstring>
#include <iostream>
#define maxn 10
#define inf 99999999
using namespace std;
char str[maxn][maxn];
int a[maxn*maxn];
int ans;
int count;
void change(int num)
{
int sh,yu,pos;
sh = num/4; yu = num%4;
if (sh != 0)//翻转上边
{
pos = num - 4;
a[pos] ^= 1;
}
if (sh != 3)//翻转下边
{
pos = num + 4;
a[pos] ^= 1;
}
if (yu != 0)//翻转左边
{
pos = num - 1;
a[pos] ^= 1;
}
if (yu != 3)//翻转右边
{
pos = num + 1;
a[pos] ^= 1;
}
a[num] ^= 1;//翻转自己
}
bool isok()
{
int tmp = a[0];
for (int i = 1; i < 16; ++i)
{
if (tmp != a[i])
return false;
}
return true;
}
void dfs(int pos,int num)
{
int i;
if (pos == 1)
{
change(num);//翻转
count++;
}
if (isok())//达到目标
{
if (ans > count)
ans = count;
return ;
}
if (num >= 15) return ;//注意这里的返回
for (i = 0; i < 2; ++i)
{
dfs(i,num + 1);
if (i == 1)//还原,枚举所有情况
{
change(num + 1);
count--;
}
}
}
int main()
{
int i,j,k;
k = count = 0;
ans = inf;
for (i = 0; i < 4; ++i)
{
scanf("%s",str[i]);
for (j = 0; j < 4; ++j)
{
if (str[i][j] == 'w')
a[k++] = 0;
else
a[k++] = 1;
}
}
for (i = 0; i < 2; ++i)//0代表不翻1代表翻
{
dfs(i,0);
}
if (ans != inf) printf("%d\n",ans);
else printf("Impossible\n");
return 0;
}



你可能感兴趣的:(game)