您的位置:首页 > 编程语言 > Go语言

POJ 1753 Flip Game(暴力+DFS)

2015-07-30 16:26 501 查看
题目链接:http://poj.org/problem?id=1753

题        意:找出是所给的4*4由b,w组成的矩阵全部变为一种字符所需的步数。

思        路:其实每格棋子最多只可以翻转一次(实际是奇数次,但这没意义),

                    只要其中一格重复翻了2次(不论是连续翻动还是不连翻动),那么它

                   以及周边的棋子和没翻动时的状态是一致的,由此就可以确定这个

                   棋盘最多只能走16步,最多只能有翻出2^16种状态。所以直接递归

                   遍历17种情况(还有0步)即可。

代码如下:#include <iostream>
using namespace std;
#include <string.h>
#include <stdio.h>
#include <queue>
#include <algorithm>
typedef long long LL;
int vis[6][6],ans,step;
int dx[5]= {0,1,-1,0,0};
int dy[5]= {0,0,0,-1,1};
int judge()
{
for( int i = 1; i < 5; i ++ )
for( int j = 1; j < 5; j ++ )
if(vis[i][j] != vis[1][1] )
return 0;
return 1;
}
void fz(int x, int y )
{
for( int i = 0; i < 5; i ++ )
vis[x+dx[i]][y+dy[i]]=!vis[x+dx[i]][y+dy[i]];
return ;
}
void dfs(int x, int y, int deep )
{
if( deep == step )
{
ans = judge();
return;
}
if( ans ) return;
if( y >= 5 ) return;//列数已经递归结束
fz(x,y);
if( x < 4 ) //看这一列是否到底,若不到,则继续;若到则从下一列的第一个位置开始
dfs(x+1, y, deep+1 );
else dfs( 1, y+1, deep+1 );
fz(x,y);//上面的操作无法使条件成立则会到这一步,把原来所翻转的棋子还原;再继续下一步
if( x < 4 ) dfs(x+1, y, deep );
else dfs( 1, y+1, deep );
return;
}
int main()
{
memset(vis, 0, sizeof(vis) );
for( int i = 1; i < 5; i ++ )
for( int j = 1; j < 5; j ++ )
{
char ch;
scanf ( " %c", &ch );
if( ch == 'b' ) vis[i][j] = 1;
}
ans = 0;//操作步数从0到16的情况
for( step = 0; step < 17; step ++ )
{
dfs(1,1,0);
if(ans) break;
}
if(ans) printf("%d\n",step);
else printf("Impossible\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  algorithm 暴力