很有意思的题目,简单粗暴
根据大白上的思路来的,但是数组下标从1开始会好处理一点
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <algorithm> using namespace std; const int maxn = 20; const int mod = 1e9+7; const int INF = 0x3f3f3f3f; typedef long long LL; int n,a[maxn][maxn],b[maxn][maxn]; int solve(int s) { memset(b,0,sizeof(b)); for(int i = 1;i<=n;++i) { if(s & (1<<(i-1)))b[1][i] = 1; else if(a[1][i]==1)return INF; } for(int i = 1;i<n;++i) for(int j = 1;j<=n;++j) { if(a[i+1][j]) { if((b[i][j-1]+b[i][j+1]+b[i-1][j]+1)%2)return INF; else {b[i+1][j] = 1;continue;} } b[i+1][j] = (b[i][j-1]+b[i][j+1]+b[i-1][j])%2?1:0; } int ans = 0; for(int i = 1;i<=n;++i) for(int j = 1;j<=n;++j) if(a[i][j]!=b[i][j])ans++; // printf("ans = %d\n",ans); return ans; } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int T;scanf("%d",&T); for(int kase = 1;kase<=T;++kase) { scanf("%d",&n); for(int i = 1;i<=n;++i) for(int j = 1;j<=n;++j) scanf("%d",&a[i][j]); int ans = INF; for(int i = 0;i<(1<<n);++i) ans = min(ans,solve(i)); if(ans>=INF)ans = -1; printf("Case %d: %d\n",kase,ans); } return 0; }
原文:http://www.cnblogs.com/GJKACAC/p/4236376.html