您的位置:首页 > 其它

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

这个题目的意思是:有一个四乘四的棋盘,每个棋子有两种状态,非黑即白,翻转一个棋子,它自身以及它上下左右的棋子都会发生翻转,问最少翻转几次(在可能的情况下),使得棋盘上的颜色统一。代码和注释如下。

#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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐