#include <stdio.h>
int main()
{
puts("转载请注明出处[vmurder]谢谢");
puts("网址:blog.csdn.net/vmurder/article/details/43483547");
}
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
题意:
多组数据、
有个n*n的正方形,然后你要对某些位置进行操作,使得最后灯的状态都变成y。
操作:这个灯位置的上下左右以及自己这五盏灯状态都取反。
然后求最小操作次数。
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
先说我自己WA了的原因:
给正方形上的点id[i][j]=++cnt赋hash,然后没清id,WA了几遍~
还自己拍极限(永远n=15),还一直过。
嗯,反正分析我代码就懂了。(ctrl+F搜索"id[")
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
然后说正经题解:
一些自由元乱取0/1 AC的都是因为数据弱,不要乱提。
首先每个位置都可以选择“操作”或者“不操作”
然后对于自由元我们可以随意选择它开还是不开,而非自由元我们则需要回代一遍出解。
然后深搜一遍就好了~
这里我们不能给所有自由元都取“不操作”,因为这样看起来少了好多次操作数,
但是实际上,这些自由元是参与非自由元求值的回代的,
所以一个自由元的不作为可能导致很多个非自由元的悲剧。
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
代码:
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 300
#define inf 0x3f3f3f3f
using namespace std;
const int dx[]={0,0,0,1,-1};
const int dy[]={0,1,-1,0,0};
bool a[N][N],x[N];
int crs[N],n,ans;
void dfs(int id,int which,int now)
{
if(id<1)
{
ans=min(ans,now);
return ;
}
if(now>=ans)return ;
if(crs[id]==which)
{
bool ret=a[id][n+1];
for(int i=which+1;i<=n;i++)ret^=(a[id][i]*x[i]);
x[which]=ret;
dfs(id-1,which-1,now+ret);
}
else {
x[which]=true;
dfs(id,which-1,now+1);
x[which]=false;
dfs(id,which-1,now);
}
return ;
}
int Gauss(int n,int m)
{
int i,j,k,id;
for(id=i=1;i<n;i++,id++)
{
for(j=id;j<=m&&!a[j][i];j++);
if(j>m){id--;continue;}
crs[id]=i;
if(id!=j)for(k=i;k<=n;k++)swap(a[id][k],a[j][k]);
for(j=id+1;j<=m;j++)if(a[j][i])for(k=i;k<=n;k++)
a[j][k]^=a[id][k];
}
for(i=id;i<=m;i++)if(a[i][n])return -1;
return id-1;
}
int id[N][N],cnt;
char src[N];
void init()
{
cnt=0,ans=inf;
memset(a,0,sizeof a);
memset(x,0,sizeof x);
memset(id,0,sizeof id);
memset(crs,0,sizeof crs);
}
int main()
{
freopen("test.in","r",stdin);
int i,j,k,g,t;
for(scanf("%d",&g);g--;)
{
init();
scanf("%d",&n);
for(i=1;i<=n;i++)for(j=1;j<=n;j++)id[i][j]=++cnt;
for(i=1;i<=n;i++)
{
scanf("%s",src+1);
for(j=1;j<=n;j++)if(src[j]=='w')
a[id[i][j]][cnt+1]=true;
}
for(i=1;i<=n;i++)for(j=1;j<=n;j++)for(k=0;k<=4;k++)
if(t=id[i+dx[k]][j+dy[k]])
a[id[i][j]][t]=true;
n*=n;
t=Gauss(n+1,n);
if(t==-1)puts("inf");
else {
dfs(t,n,0);
printf("%d\n",ans);
}
}
return 0;
}