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;
}
题 意:找出是所给的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;
}
相关文章推荐
- Javascript SHA-1:Secure Hash Algorithm
- 用fail2ban阻止SSH和VSFTP暴力破解密码
- [转]可视化的数据结构和算法
- 统计文件中不小于某一长度的单词的个数(泛型算法实现)
- 使用他人的MD5编码类,修改形成密码串
- Extracting Structured Data from Web Pages
- (译)Cocos2d_for_iPhone_1_Game_Development_Cookbook:1.13使用CCTexture2DMutable调换调色盘
- Java中3DES加密
- Refactoring Notes-Refactoring Methods(3)
- 图书馆管理程序~~不过貌似功能!!有空再修修
- 2015BJOI day1第三题 糖果candy
- trainging contest#2(2011成都现场赛)I BY Hyoga
- C/C++头文件包含内容概览
- 堆栈的应用(1) 平衡符号 C++实现
- 程序员编程艺术第一章、左旋转字符串
- 程序员编程艺术:第三章续、Top K算法问题的实现
- 程序员编程艺术:第四章、现场编写类似strstr/strcpy/strpbrk的函数
- 十四、第三章再续:快速选择SELECT算法的深入分析与实现
- 程序员编程艺术:第七章、求连续子数组的最大和
- 程序员编程艺术:第八章、从头至尾漫谈虚函数