rt,我们把3×3改成n×n,3≤n≤18。
思路是:枚举第一行的每个点按与不按,然后对于后面的每一行的每个点,若上一行这个点是0就按,否则就不按,最后判断最后一行是否全是1。
这是我的代码:
#include<cstdio>
#include<cstring>
using namespace std;
int n,sum=1e9;
int a[20][20];
bool f[20];
int c[20][20];
int min(int x,int y){return x<y?x:y;}
int check()
{
int ans=0;
memcpy(c,a,sizeof(c));
for(int i=1;i<=n;i++)
if(f[i])
{
c[2][i]^=1;
c[1][i-1]^=1;c[1][i+1]^=1;
c[1][i]^=1;
ans++;
}
for(int i=2;i<=n;i++)
for(int j=1;j<=n;j++)
if(!c[i-1][j])
{
c[i-1][j]^=1;c[i+1][j]^=1;
c[i][j-1]^=1;c[i][j+1]^=1;
c[i][j]^=1;
ans++;
}
for(int i=1;i<=n;i++)
if(!c[n][i]) return -1;
return ans;
}
void dfs(int x)
{
if(x==n+1)
{
int k=check();
sum=min(sum,(k==-1)?1e9:k);
return ;
}
dfs(x+1);
f[x]=true;
dfs(x+1);
f[x]=false;
return ;
}
int main()
{
freopen("lights.in","r",stdin);
freopen("lights.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) scanf("%d",&a[i][j]);
dfs(1);
printf("%d",sum);
return 0;
}
这是数据:
6
0 0 0 1 1 1
0 0 1 1 0 0
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 1 0 1
0 0 0 0 0 1
应该输出17,我输出16。
求大佬帮忙调一下/kel