题目地址
http://poj.org/problem?id=1681
题目大意
- 给定一个方阵初始化为w, y二种状态
- 每次刷一个点,周围四个点的状态会改变
- 要使得全部状态最后为y,求刷最少的点是多少?
解题思路
- 枚举
- 分析局部状态,当第一行确定之后,则第二行是确定的,以此类推
- 只需要枚举第一行即可,然后判断最后一行是否符合要求
Code
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <map>
#include <vector>
#include <math.h>
#include <algorithm>
#define INF 0x3fffffff
#define N 40
using namespace std;
typedef long long LL;
int init[N][N];
int press[N][N];
int first[N];
int t;
int n , m;
bool C() {
for (int i = 1; i <= n; i++) {
press[1][i] = first[i];
}
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= n; j++) {
press[i][j] = (init[i-1][j] + press[i-1][j] + press[i-2][j] + press[i-1][j-1] + press[i-1][j+1]) % 2;
}
}
for (int i = 1; i <= n; i++) {
if (init[n][i] != ((press[n][i] + press[n-1][i] + press[n][i-1] + press[n][i+1]) % 2)) {
return false;
}
}
return true;
}
int stat() {
int ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (press[i][j] == 1) ans++;
}
}
return ans;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#else
//
#endif
cin >> t;
for (int x = 1; x <= t; x++) {
cin >> n;
memset(init, 0, sizeof(init));
memset(press, 0, sizeof(press));
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
char c;
cin >> c;
if (c == 'w') {
init[i][j] = 1;
}
}
}
int ans = INF;
for (int i = 0; i <= ((1 << n)-1); i++) {
for (int j = 0; j < n; j++) {
first[j+1] = ((1 << j) & i) >> j;
}
if (C()) {
ans = min(ans, stat());
}
memset(press, 0, sizeof(press));
}
if (ans == INF) {
cout << "inf" << endl;
} else {
cout << ans << endl;
}
}
return 0;
}