poj1753和2965题(棋盘上的棋子翻转最后达到同一状态)
2017-03-10 20:22
267 查看
想想还是得多刷点题。有两道类似的题,都用了深搜和枚举,分别是POJ上的1753题和2965题,先粘贴如下,这个代码是参考别人的代码。思路很清晰,借鉴过来。
Flip Game(1753题)
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 21024 Accepted: 9108
Description
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it’s black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa.
The pieces to be flipped are chosen every round according to the following rules:
Choose any one of the 16 pieces.
Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).
Consider the following position as an example:
bwbw
wwww
bbwb
bwwb
Here “b” denotes pieces lying their black side up and “w” denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become:
bwbw
bwww
wwwb
wwwb
The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal.
Input
The input consists of 4 lines with 4 characters “w” or “b” each that denote game field position.
Output
Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write 0. If it’s impossible to achieve the goal, then write theword”Impossible” (without quotes).
Sample Input
bwwb
bbwb
bwwb
bwww
Sample Output
4
这个题目的意思是:有一个四乘四的棋盘,每个棋子有两种状态,非黑即白,翻转一个棋子,它自身以及它上下左右的棋子都会发生翻转,问最少翻转几次(在可能的情况下),使得棋盘上的颜色统一。代码和注释如下。
这个题大致同前一题相似,只是翻转的过程和最后的状态不同,翻转时该点所在的整行整列都会发生变化,同时最后的状态是棋盘都是“-”的状态,而且多了要记录下翻转的点的过程。同样采取搜索和枚举,每个点有翻转和不翻转两种状态。代码和注释如下。
Flip Game(1753题)
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 21024 Accepted: 9108
Description
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 squares. One side of each piece is white and the other one is black and each piece is lying either it’s black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa.
The pieces to be flipped are chosen every round according to the following rules:
Choose any one of the 16 pieces.
Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).
Consider the following position as an example:
bwbw
wwww
bbwb
bwwb
Here “b” denotes pieces lying their black side up and “w” denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become:
bwbw
bwww
wwwb
wwwb
The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal.
Input
The input consists of 4 lines with 4 characters “w” or “b” each that denote game field position.
Output
Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write 0. If it’s impossible to achieve the goal, then write theword”Impossible” (without quotes).
Sample Input
bwwb
bbwb
bwwb
bwww
Sample Output
4
这个题目的意思是:有一个四乘四的棋盘,每个棋子有两种状态,非黑即白,翻转一个棋子,它自身以及它上下左右的棋子都会发生翻转,问最少翻转几次(在可能的情况下),使得棋盘上的颜色统一。代码和注释如下。
#include<stdio.h>//1753棋盘翻转 #include<iostream> using namespace std; int chess[4][4]; int c=33; void build()//将棋盘的颜色以标记化 { char c; int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) { cin>>c;//此处采用c++的输入,之前用C语言一直出错,原因在于C语言的输入中会把换行也当成是一个字符 if(c=='w') chess[i][j]=0; else chess[i][j]=1; } } void turn(int x,int y)//翻转 { if(x>=0&&x<=3&&y>=0&&y<=3)//如果是在棋盘的四周,那么翻转的时候不一定上下左右都存在 chess[x][y]=!chess[x][y]; } void flip(int s)//一个棋子变化,周围四个都要变化 { int i=s/4;//行 int j=s%4;//列 turn(i,j); turn(i+1,j); turn(i,j+1); turn(i-1,j); turn(i,j-1); } int complete()//判断棋盘是否变成同一的颜色 { int i,j,s1=0; for(i=0;i<4;i++) for(j=0;j<4;j++) s1+=chess[i][j]; if(s1%16) return 0; else return 1; } void dfs(int s,int b)//进行深搜.s代表当前的方格,b代表翻转的方格数 { if(complete())//如果是同一颜色,找到最终状态 { if(c>b) c=b; return; } if(s>=16)//如果遍历完 return; dfs(s+1,b);//不翻转,一直往下进行搜索 flip(s);//回溯到上一层,翻转此棋子 dfs(s+1,b+1);//再进行往下搜索的过程 flip(s);//回到上一层,把棋子的状态恢复 } int main() { build();//将棋盘的颜色以标记化 dfs(0,0); if(c==33)//由于翻转次数最多为4*4*2=32次 printf("Impossible\n"); else printf("%d\n",c); return 0; }
2965题
这个题大致同前一题相似,只是翻转的过程和最后的状态不同,翻转时该点所在的整行整列都会发生变化,同时最后的状态是棋盘都是“-”的状态,而且多了要记录下翻转的点的过程。同样采取搜索和枚举,每个点有翻转和不翻转两种状态。代码和注释如下。
#include<stdio.h> #include<iostream> using namespace std; int location[4][4]; int cnt=33; int x[16],y[16];//临时的把这些点都记录下来 int ansx[16],ansy[16];//最终的结果 void build() { char c; int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) { cin>>c; if(c=='+') location[i][j]=0; else location[i][j]=1; } } int success()//判断是否达到了最后的状态 { int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) { if(location[i][j]==0) return 0; } return 1; } void switching(int s) { int a=s/4; int b=s%4; int i,j; for(j=0;j<4;j++) { location[a][j]=!location[a][j]; } for(i=0;i<4;i++) { location[i][b]=!location[i][b]; } location[a][b]=!location[a][b];//该点在前面的过程中被翻转两次,相当翻转回来,再翻转一次 } void dfs(int s,int b) { int i; if(success()) { if(cnt>b) { cnt=b; for(i=0;i<cnt;i++) { ansx[i]=x[i];//如果此次搜索成功了,那么在此过程中翻转的点就是问题的解 ansy[i]=y[i]; } } return; } if(s>=16) return ; dfs(s+1,b); switching(s); x[b]=s/4;//记录所有翻转的点 y[b]=s%4; dfs(s+1,b+1); switching(s); } int main() { build(); dfs(0,0); printf("%d\n",cnt); for(int i=0;i<cnt;i++) printf("%d %d\n",ansx[i]+1,ansy[i]+1); }
相关文章推荐
- 在4x4的棋盘上摆满了黑白棋子,黑白两色的位置和数目随机其中左上角坐标为(1,1),右下角坐标为(4,4),现在依次有一些翻转操作,要对一些给定支点坐标为中心的上下左右四个棋子的颜色进行翻转,请计算出翻转后的棋盘颜色。
- Android实训案例(八)——单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局
- Android实训案例(八)——单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局
- Android实训案例(八)——单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局
- POJ1753 状态压缩(+BFS) + 棋盘问题
- POJ1753 棋盘翻转(位压缩+广度优先搜索)
- poj 1753 棋盘翻转(BFS+状态压缩)
- POJ1753 棋盘翻转(位压缩+广度优先搜索)
- 棋子翻转-java
- 美团-棋子翻转-Java
- 棋子翻转
- 100个房间,100个服务员依次做相反操作,求最后状态
- LA --- 2965 Jurassic Remains 数相同的大写字母 【思维 + 状态压缩枚举 + 中途相遇法(折半搜索)】
- The Pilots Brothers' refrigerator(POJ 2965)(dfs枚举+状态压缩)
- 棋盘 围棋? 黑白棋子? 我忘记了
- POJ 2993-Emag eht htiw Em Pleh(模拟-根据棋子位置还原棋盘)
- [51nod1142] 棋子遍历棋盘
- 【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest B】【构造】Black and White 构造棋盘使得两种棋子联通块数恰为x与y
- mysql 安装到最后一步时,start service 为失败状态 请问是什么原因
- 1114 Piggy-Bank - 完全背包 恰好达到状态最小价值