题目链接:
http://poj.org/problem?id=1753
题意:
4*4棋盘,每个格子上黑或白棋子一枚,翻转棋子时相邻的四个棋子都会随之改变颜色,问最小翻转步数,若无输出“Impossible”
思路:
对于这种翻转游戏,翻转顺序不会影响结果,直接枚举即可,时间复杂度2^16
核心算法是从16个数中分别选出1.2.3.....16个数
代码:
#include <stdio.h>
int check = 0;
int isFinish(int arr[6][6], int sum){
int c = 1;
for (int i = 1; i <= 4&&c; i++){
for (int j = 1; j <= 4&&c; j++){
if (arr[i][j] == 1){
c = 0;
}
}
}
if (c){
check = sum;
return 1;
}
else{
c = 1;
for (int i = 1; i <= 4 && c; i++){
for (int j = 1; j <= 4 && c; j++){
if (arr[i][j] == 0){
c = 0;
}
}
}
if (c){
check = sum;
return 1;
}
}
return 0;
}
void search(int arr[6][6], int pos,int x,int sum){
if (check) return;
int i = (pos - 1) / 4 + 1, j = pos % 4;
j = j == 0 ? 4 : j;
arr[i][j] = 1 - arr[i][j];
arr[i + 1][j] = 1 - arr[i + 1][j];
arr[i][j + 1] = 1 - arr[i][j + 1];
arr[i - 1][j] = 1 - arr[i - 1][j];
arr[i][j - 1] = 1 - arr[i][j - 1];
if (x != 1){
for (int k = pos + 1; k <= 16 - (x - 1) + 1; k++)
search(arr, k, x - 1, sum);
}
else{
isFinish(arr, sum);
}
arr[i][j] = 1 - arr[i][j];
arr[i + 1][j] = 1 - arr[i + 1][j];
arr[i][j + 1] = 1 - arr[i][j + 1];
arr[i - 1][j] = 1 - arr[i - 1][j];
arr[i][j - 1] = 1 - arr[i][j - 1];
return;
}
int main(){
int arr[6][6] = { 0 };
char str[5];
for (int i = 1; i <= 4; ++i){
scanf("%s", str);
int t = 0;
for (int j = 0; j < 4; ++j){
if (str[j] == 'w')//b=0,w=1;
arr[i][j+1] = 1;
}
}
//in
if (isFinish(arr, 0)) printf("0\n");
else{
for (int i = 1; i <= 16 && !check; ++i){
for (int j = 1; j <= 16 - i + 1 && !check; ++j){
search(arr, j, i, i);
}
}
if (check) printf("%d\n", check);
else printf("Impossible\n");
}
return 0;
}