约翰知道,那些高智力又快乐的奶牛产奶量特别高.所以他做了一个翻瓦片的益智游戏来娱乐奶牛.在一个M×N(1≤M,N≤15)的骨架上,每一个格子里都有一个可以翻转的瓦片.瓦片的一面是黑色的,而另一面是白色的.对一个瓦片进行翻转,可以使黑变白,也可以使白变黑.然而,奶牛们的蹄子是如此的巨大而且笨拙,所以她们翻转一个瓦片的时候,与之有公共边的相邻瓦片也都被翻转了.那么,这些奶牛们最少需要多少次翻转,使所有的瓦片都变成白面向上呢?如杲可以做到,输出字典序最小的结果(将结果当成字符串处理).如果不能做到,输出“IMPOSSIBLE”.
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
void flip(vector<vector<int>>& pad, int M, int N, int x, int y) {
pad[x][y] = pad[x][y] == 1 ? 0 : 1;
if (x - 1 >= 0) {
pad[x - 1][y] = pad[x - 1][y] == 1 ? 0 : 1;
}
if (x + 1 < M) {
pad[x + 1][y] = pad[x + 1][y] == 1 ? 0 : 1;
}
if (y - 1 >= 0) {
pad[x][y - 1] = pad[x][y - 1] == 1 ? 0 : 1;
}
if (y + 1 < N) {
pad[x][y + 1] = pad[x][y + 1] == 1 ? 0 : 1;
}
}
int main() {
int M; int N;
scanf("%d %d", &M, &N);
vector<vector<int>> pad(M, vector<int>(N));
vector<vector<int>> copypad(pad);
vector<vector<int>> ans(M, vector<int>(N, 0));
vector<vector<int>> anstem(M, vector<int>(N, 0));
int minitime = INT_MAX;
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++) {
scanf("%d", &pad[i][j]);
}
for (int i = 0; i < (1 << N); i++) {
int time = 0;
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++) {
copypad[i][j] = pad[i][j];
}
for(int i=0;i<M;i++)
for (int j = 0; j < N; j++) {
anstem[i][j]=0;
}
//第一行变化
for (int j = 0; j < N; j++) {
if (((i >> (j)) & 1) == 1) {
anstem[0][N - 1 - j] = 1;
flip(copypad, M, N, 0, N - 1 - j);
time++;
}
}
for (int line = 1; line < M; line++) {
for (int j = 0; j < N; j++) {
if (copypad[line - 1][j] == 1) {
flip(copypad, M, N, line, j);
anstem[line][j] = 1;
time++;
}
}
}
//判断最后一行是否全0
for (int j = 0; j < N; j++) {
if (copypad[M - 1][j] == 1) {
break;
}
if (j == N - 1 && time < minitime) {
minitime = time;
ans = anstem;
}
}
}
if (minitime == INT_MAX) {
printf("IMPOSSIBLE");
}
else {
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++) {
printf("%d%c", ans[i][j], j == N - 1 ? '\n' : ' ');
}
}
return 0;
}

1077

被折叠的 条评论
为什么被折叠?



