求助,老师出了一道这题的加强版
查看原帖
求助,老师出了一道这题的加强版
195331
Mine_KingCattleya楼主2020/5/24 13:52

rt,我们把3×33 \times 3改成n×nn \times n3n183\le n \le18
思路是:枚举第一行的每个点按与不按,然后对于后面的每一行的每个点,若上一行这个点是00就按,否则就不按,最后判断最后一行是否全是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

应该输出1717,我输出1616
求大佬帮忙调一下/kel

2020/5/24 13:52
加载中...