POJ 1753 Flip Game
[★☆☆☆☆]枚举
题目大意:
有4*4的正方形,每个格子要么是黑色,要么是白色,当把一个格子的颜色改变(黑->白或者白->黑)时,其周围上下左右(如果存在的话)的格子的颜色也被反转,问至少反转几个格子可以使4*4的正方形变为纯白或者纯黑?
输入格式:
4*4矩阵(’b’代表黑,’w’代表白)
输出格式:
最小翻转次数
样例
输入:
bwwb
bbwb
bwwb
bwww输出:
4解题思路:
水题,暴搜2^16轻松过。我做这道题写复杂了,适用于更大的范围。
暴搜是O(2^(n^2)),我用的是O(2^n)。
枚举第一排的2^n种方法。剩下的几排根据前一排对应的位置来决定是否翻转。
需要注意的问题是原数据的保护,我用了另外的数组copy。代码
#include <iostream>
using namespace std;
const int INF = 1e9 + 7;
char map[5][5];
char mapc[5][5];
int ans;
void sc() {
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
cout << map[i][j];
}
cout << endl;
}
cout << endl;
}
void f(int x, int y) {
if (map[x][y] == 'b') map[x][y] = 'w';
else map[x][y] = 'b';
}
void fc(int x, int y) {
if (mapc[x][y] == 'b') mapc[x][y] = 'w';
else mapc[x][y] = 'b';
}
void fz (int x, int y) {
f(x,y);
if (x-1 >= 1) f(x-1,y);
if (x+1 <= 4) f(x+1,y);
if (y-1 >= 1) f(x,y-1);
if (y+1 <= 4) f(x,y+1);
}
void fzc (int x, int y) {
fc(x,y);
if (x-1 >= 1) fc(x-1,y);
if (x+1 <= 4) fc(x+1,y);
if (y-1 >= 1) fc(x,y-1);
if (y+1 <= 4) fc(x,y+1);
}
void fzall() {
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
f(i, j);
}
}
}
void cp() {
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
mapc[i][j] = map[i][j];
}
}
}
void ss (int c, int res) {
if (c == 5) {
cp();
for (int i = 2; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
if (mapc[i-1][j] == 'w') { fzc(i,j); res++;}
}
}
if (mapc[4][1] == 'b' && mapc[4][2] == 'b' && mapc[4][3] == 'b'&& mapc[4][4] == 'b')
ans = min(ans, res);
return;
}
else {
ss(c+1, res);
fz(1, c);
ss(c+1, res+1);
fz(1, c);
}
}
int main() {
ans = INF;
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
cin >> map[i][j];
}
}
ss (1, 0);
fzall();
ss (1, 0);
if (ans == INF) cout << "Impossible\n";
else cout << ans << endl;
return 0;
}