UVA11464 Even Parity 搜索+递推

问题描述

UVA11464


题解

第一直觉爆搜。

发现 (N le 15) ,然后后面每行都可以通过第一行递推出来。

爆搜第一行,递推后面+check


(mathrm{Code})

#include<bits/stdc++.h>
using namespace std;

template <typename Tp>
void read(Tp &x){
	x=0;char ch=1;int fh;
	while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
	if(ch=='-') ch=getchar(),fh=-1;
	else fh=1;
	while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	x*=fh;
}

const int maxn=17;
const int INF=0x3f3f3f3f;

int T,cas;

int n;
int a[maxn][maxn],b[maxn][maxn];

int ans;

int calc(){
	int res=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(a[i][j]==1&&b[i][j]==0) ++res;
		}
	}
	return res;
}

bool check(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			int k=a[i][j-1]+a[i][j+1]+a[i-1][j]+a[i+1][j];
			if(k&1) return false;
		}
	}
	return true;
}

void rebuild(){
	for(int i=2;i<=n;i++){
		for(int j=1;j<=n;j++) a[i][j]=b[i][j];
	}
}

void dp(){
	for(int i=2;i<=n;i++){
		for(int j=1;j<=n;j++){
			int k=a[i-1][j-1]+a[i-1][j+1]+a[i-2][j];
			if(k&1) a[i][j]=1;
		}
	}
	if(!check()){
		rebuild();return ;
	}
	ans=min(ans,calc());
	rebuild();
}

void dfs(int step){
	if(step==n+1){
		dp();return;
	}
	if(a[1][step]){
		dfs(step+1);return;
	}
	dfs(step+1);
	a[1][step]=1;
	dfs(step+1);
	a[1][step]=0;
}

void Init(){
	read(n);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			read(a[i][j]);
			b[i][j]=a[i][j];
		}
	}
}

void solve(){
	dfs(1);
	if(ans==INF) ans=-1;
	printf("Case %d: %d
",cas,ans);
}

void reset(){
	ans=INF;
	memset(a,0,sizeof(a));//错误笔记:多测不清空,*****
	memset(b,0,sizeof(b));
}

int main(){
//	freopen("UVA11464.in","r",stdin);freopen("UVA11464.out","w",stdout);
	read(T);
	while(T--){
		++cas;
		reset();
		Init();solve(); 
	}
	return 0;
}
原文地址:https://www.cnblogs.com/liubainian/p/11748889.html