|
? Flip Game
| Time Limit: 1000MS |
? |
Memory Limit: 65536K |
| Total Submissions: 30449 |
? |
Accepted: 13232 |
?
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 the word Impossible (without quotes).
Sample Input
bwwb
bbwb
bwwb
bwww
Sample Output
4
Source Northeastern Europe 2000
?
?
import java.util.ArrayDeque;
import java.util.Scanner;
/*
* 首先有两点:
* 1.两颗棋子的翻动顺序不影响翻动结果
* 2.一颗棋子的偶数次翻动与0次翻动效果等同,一颗棋子的奇数次翻动与1次翻动效果等同
*
*/
public class poj1753 {
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
while (cin.hasNext()){
ArrayDeque
qu=new ArrayDeque
();//
Java队列 Node node=new Node(0,0,0); for (int i=1;i<=4;i++){ String s=cin.next(); for (int j=0;j
0xFFFF) continue;//所有可能状态全部入队,不在有新的状态入队,以下循环体不再执行 for (int i=tou.location+1;i<=16;i++){//从当前头节点的位置向后找,1到16表示16个棋格的翻动 //状态(后修改),当前为第i个棋格的翻动,翻动棋格数为队头棋格翻动数+1 node=new Node(0,i,tou.ways+1); //翻动当前棋子:队头与当前棋格翻动状态(例如左上角i=1状态为1后15个 0,即1000000000000000)的“异或” node.state=tou.state^(1<<(16-i)); //翻动上相邻棋子:i-4>=1判断当前棋格是否有上相邻棋子 if (i-4>=1) node.state^=1<<(16-i+4); //翻动下相邻棋子:i+4<=16判断当前棋格是否有下相邻棋子 if (i+4<=16) node.state^=1<<(16-i-4); //翻动右相邻棋子:4的倍数为棋盘的右边界,无右相邻棋子,16-i再减1位运算少向左移动一位,所以是右边 if (i%4!=0) node.state^=1<<(16-i-1); //翻动左相邻棋子:i-1为有边界时,加1后的i就是左边界 if ((i-1)%4!=0) node.state^=1<<(16-i+1); qu.add(node); } } if (!flag)//找不出合适翻动 System.out.println(Impossible); } } } class Node{ int state;//状态:state的二进制位表示16个棋格的状态 int location;//位置:当前状态为第i个棋格的翻动 int ways;//翻动棋格数 Node (int state,int location,int ways){ this.state=state; this.location=location; this.ways=ways; } }
?
?
?
?
?
?
?
?
|