TC-572-D1L2 (双向搜索+记忆化)

solution:

这一题是比较难实现的双向搜索题:(字符串+双向搜索+hash记忆化)
我们可以先把K的前半部分枚举出来,并将得出的所有结果和题目给的n个数的每一个数的前半部分都比对一遍,得到它和每一个数有几位相同,并hash存到map中去。
然后我们枚举K的后半部分,并将得出的所有结果和题目给的n个数的每一个数的后半部分都比对一遍,得到它和每一个数有几位相同。这样我们可以得到:对于每一个枚举出的结果,他所对应的前半部分和n个数中每个数比对后应该有几位相同,将你得到的结果与标准值取差然后hash,看map中是否有一样的值存在。(存在就表示你找到了一个(也可能是多个)解,然后判断一下输出即可)

当然,这一题还难在细节,要仔细一点(前导零,字符串的处理,如何hash,怎样比对,分类讨论应该输出什么........)

=>

code:

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>

#define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int

using namespace std;

int n,m,s,su,ans,f;
int l[11],r[55];
int b[55],a[55][11];
char ch[55];

map<int,int> h;

inline int qr(){
	char ch;
	while((ch=getchar())<'0'||ch>'9');
	int res=ch^48;
	while((ch=getchar())>='0'&&ch<='9')
		res=res*10+(ch^48);
	return res;
}

inline int haxi(){
	unsigned int sdf=11;
	for(rg i=1;i<=n;++i){
		sdf=(sdf+b[i])*7+13;
	}
	return sdf%inf;
}

inline int bint(int i,int j){
	int res=0;
	for(;i<=j;++i)
		res=res*10+l[i];
	return res;
}

inline void yu(int t){
	if(t>m){
		for(rg i=1;i<=n;++i){ b[i]=0;
			for(rg j=1;j<=m;++j)
				b[i]+=(a[i][j]==l[j]?1:0);
			if(b[i]>r[i])return ;
		}
		int sdf=haxi(),lkj=bint(1,m);
		if(h.find(sdf)!=h.end()) h[sdf]=-1;
		else h[sdf]=lkj;
		return ;
	}
	for(rg i=0;i<=9;++i)
		l[t]=i, yu(t+1);
}

inline void dfs(int t){
	if(t>s){
		for(rg i=1;i<=n;++i){ b[i]=0;
			for(rg j=m+1;j<=s;++j)
				b[i]+=(a[i][j]==l[j]);
			if(b[i]>r[i])return ;
			b[i]=r[i]-b[i];
		}
		int sdf=haxi();
		if(h.find(sdf)!=h.end()){
			if((su=h[sdf])<0||ans)
				puts("Ambiguity"),exit(0);
			else{
				int lkj=bint(m+1,s);
				for(rg i=m+1;i<=s;++i)su*=10;
				ans=su+lkj;
			}
		}
		return ;
	}
	for(rg i=0;i<=9;++i)
		l[t]=i,dfs(t+1);
}


int main(){
	//freopen("passwd.in","r",stdin);
    //freopen("passwd.out","w",stdout);
	n=qr(); s=qr(); m=s/2;
	for(rg i=1;i<=n;++i){
		cin>>ch;r[i]=qr();
		for(rg j=1;j<=s;++j)
			a[i][j]=ch[j-1]-'0';
	} yu(1); dfs(m+1);
	if(ans){ int su=ans;
		for(rg i=1;i<=s;++i){
			if(!su)printf("0");
			su/=10;
		}printf("%d",ans);
	}
	else puts("Liar");
	return 0;
}
posted @ 2019-01-23 16:56  一只不咕鸟  阅读(205)  评论(1编辑  收藏  举报