Flip Game
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 51906 Accepted: 21886
Description
Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16
it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their
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
题意:4×4的黑白棋盘,规定翻转一个棋子的同时也要翻转它的上、下、左、右的棋子,问给定一个棋盘的棋子状态,至少需要翻转多少次棋子,能使得所有棋子都是同色朝上。
思路:一开始只想到暴力搜索,但具体怎么写还是不会,查阅到一篇博主的文章,原博主题解链接 才有了想法,几乎是照搬的题解了。我好菜。。
总结思路:
1、棋子翻转奇数次才有意义。
2、状态总数仅有2^16,所以可以暴力搜索。
3、用一个int的16位来保存16个棋子的状态。
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int chess = 0;
int state[16];
//得到state数据
void init() {
for (int i = 1; i <= 16; i++) {
int v = 0, k = 1 << (i - 1);
v |= k;
if ((i + 1) % 4 != 1) v |= k << 1;
if ((i - 1) % 4 != 0) v |= k >> 1;
if (i > 4) v |= k >> 4;
if (i < 13) v |= k << 4;
state[i - 1] = v;
}
}
//翻转第i个棋子
void flip(int i) { chess ^= state[i]; }
//判断是否完成
bool check() { return chess == 0 || chess == 0xffff; }
//寻找解 总共还要翻n个,当前翻第i个
bool find(int n, int i) {
if (n == 0) return check();
for (; i < 16; i++) {
flip(i);
if (find(n - 1, i + 1)) return true;
flip(i); //遍历一种后翻转回来以便下次遍历
}
return false;
}
int main() {
init();
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
chess <<= 1;
if (getchar() == 'b') chess |= 1;
}
getchar();
}
for (int i = 0; i < 16; i++) {
if (find(i, 0)) {
cout << i;
system("pause");
return 0;
}
}
cout << "Impossible";
system("pause");
return 0;
}