枚举第一行的情况就能递推出下面的各个行的。
瞎退,细节挺多的,代码弱的容易wa细节(就是我
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <stack>
#include <queue>
#include <list>
#include <cmath>
using namespace std;
#define cir(a,b) memset(a,b,sizeof a)
typedef long long LL;
const int maxn = 100000+10;
const int INF = 1e9 + 10;
int n ;
int m;
int s[20][20];
int s1[20][20];
int judge()
{
bool flag = true;
int time = 0;
for(int i=0; i<n-1; i++)
{
for(int j=0; j<n; j++)
{
int sum = 0;
if(i==0 && j==0)
{
sum += s[i][j+1];
}
if(i==0 && j!=0)
{
sum +=(s[i][j-1]+s[i][j+1]);
}
if(i!=0 && j==0)
{
sum +=(s[i-1][j]+s[i][j+1]);
}
if(i!=0 && j!=0)
{
sum +=(s[i-1][j]+s[i][j+1]+s[i][j-1]);
}
if(sum == 2 || sum == 0)
{
if(s[i+1][j] == 1)
{
flag = false;
}
}
if(sum == 1 || sum == 3)
{
if(s[i+1][j] == 0)
{
time ++;
s[i+1][j]=1;
}
}
}
}
for(int j=0; j<n; j++)
{
if(j==0)
{
// cout << s[n-1-1][j]+s[n-1][j+1] <<" ";
if((s[n-1-1][j]+s[n-1][j+1])%2 != 0)
{
flag = false ;
break;
}
}
else
{
// cout << (s[n-1-1][j]+s[n-1][j+1]+s[n-1][j-1]) <<" ";
if((s[n-1-1][j]+s[n-1][j+1]+s[n-1][j-1])%2 !=0)
{
flag = false;
}
}
}
// cout << endl;
// for(int i=0;i<n;i++)
// {
// for(int j=0;j<n;j++)
// {
// cout << s[i][j] << " ";
// }
// cout << endl;
// }
// cout << "***********" << endl;
if(!flag)
{
return INF;
}
else
{
return time;
}
}
int main()
{
int k = 1;
cin >> m;
while(m--)
{
cin >> n;
memset(s,0,sizeof(s));
memset(s1,0,sizeof(s1));
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
cin >> s[i][j];
s1[i][j] = s[i][j];
}
}
int sum = INF;
for(int i=0; i< (1<<n); i++)
{
int time = 0;
for(int j=0; j<n; j++)
{
if( (i>>j) & 1)
{
if(s[0][j]==0)
{
s[0][j] = 1;
time ++;
}
}
}
sum = min(judge()+time,sum);
for(int j=0; j<n; j++)
{
for(int k=0; k<n; k++)
{
s[j][k] = s1[j][k];
}
}
}
printf("Case %d: ",k++);
if(sum >= INF) cout << "-1" <<endl;
else cout << sum <<endl;
}
return 0;
}