题目描述:
解法一:和以前摆格子的题目差不多.但是不一样.这个十字只有一种摆放方式,如果确定了上一行的颜色,那么这一行怎么摆就确定了.因此只需要确定第一行,然后往下走就行.i,j是十字的中心.(ij是否放只与它的上一个有关,并且只有一种放法)
解法二:高斯消元.重点是当有自由变元的时候枚举然后倒着推上去..
题解:
rt
重点:
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <ctype.h>
#include <limits.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
#define CLR(a) memset(a, 0, sizeof(a))
#define REP(i, a, b) for(int i = a;i < b;i++)
#define REP_D(i, a, b) for(int i = a;i <= b;i++)
typedef long long ll;
using namespace std;
const int maxn = 300+100;
const int INF = 1e9;
int dx[]= {-1, 0, 1, 0}, dy[]= {0, 1, 0, -1};
int a[maxn][maxn], x[maxn];
int equ, var;
char s[maxn][maxn];
int free_x[maxn];
int free_num;
int n;
int gauss()
{
free_num=0;
int k, col;
for(k=0, col=0; k<equ&&col<var; k++,col++)
{
int max_k=k;
for(int i=k+1; i<equ; i++)
{
if(abs(a[i][col])>abs(a[max_k][col]))
{
max_k = i;
}
}
if(a[max_k][col]==0)
{
free_x[free_num++]=col;
k--;
continue;
}
if(k!=max_k)
{
for(int i=col; i<=var; i++)
{
swap(a[k][i], a[max_k][i]);
}
}
for(int i=k+1; i<equ; i++)
{
if(a[i][col])
{
for(int j=col+1; j<=var; j++)
{
a[i][j]^=a[k][j];
}
a[i][col]=0;
}
}
}
for(int i=k; i<equ; i++)
{
if(a[i][col])
{
return -1;
}
}
if(k==var)
{
for(int i=var-1; i>=0; i--)
{
x[i]=a[i][var];
for(int j = i+1; j<var; j++)
{
x[i] ^= (a[i][j]&x[j]);
}
}
int ans=0;
for(int i=0; i<var; i++)
{
ans += x[i];
}
return ans;
}
int S = (1<<(var-k))-1;
int ans = INF;
int cnt;
for(int sta=0; sta<=S; sta++)
{
cnt=0;
for(int i=0; i<free_num; i++)
{
if(((1<<i)&sta))
{
x[free_x[i]]=1;
cnt++;
}
else
{
x[free_x[i]]=0;
}
}
for(int i=k-1; i>=0; i--)
{
int index=i;
for(int j=i; j<var; j++)
{
if(a[i][j]!=0)
{
index=j;
break;
}
}
x[index]=a[i][var];
for(int j=index+1; j<var; j++)
{
x[index]^=(a[i][j]&x[j]);
}
cnt += x[index];
}
ans = min(cnt, ans);
}
return ans;
}
int check(int x, int y)
{
if(x>=0&&x<n&&y>=0&&y<n)
return 1;
return 0;
}
void solve()
{
equ=n*n;
var=equ;
CLR(a);
CLR(x);
REP(i, 0, n)
{
REP(j, 0, n)
{
int tmp=i*n+j;
if(s[i][j]=='y')
{
a[tmp][var]=0;
}
else
{
a[tmp][var]=1;
}
a[tmp][tmp]=1;
for(int k=0; k<4; k++)
{
int newI=i+dx[k], newJ=j+dy[k];
if(check(newI, newJ))
{
int goal=newI*n+newJ;
a[goal][tmp]=1;
}
}
}
}
int ans=gauss();
if(ans==-1)
{
printf("inf\n");
}
else
{
printf("%d\n", ans);
}
}
int main()
{
//freopen("4Din.txt", "r", stdin);
//freopen("4Dout.txt", "w", stdout);
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d", &n);
REP(i, 0, n)
{
scanf("%s", s[i]);
}
solve();
}
return 0;
}