jzoj 3888. 【NOIP2014模拟10.25B组】正确答案 (Standard IO)

Description
小H与小Y刚刚参加完UOIP外卡组的初赛,就迫不及待的跑出考场对答案。
“吔,我的答案和你都不一样!”,小Y说道,”我们去找神犇们问答案吧”。
外卡组试卷中共有m道判断题,小H与小Y一共从其他n个神犇那问了答案。之后又从小G那里得知,这n个神犇中有p个考了满分,q个考了零分,其他神犇不为满分或零分。这可让小Y与小H犯了难。你能帮助他们还原出标准答案吗?如有多解则输出字典序最小的那个。无解输出-1。

Input
第一行四个整数n, m, p, q,意义如上描述。
接下来n行,每一行m个字符’N’或’Y’,表示这题这个神犇的答案。

Output
仅一行,一个长度为m的字符串或是-1。

Sample Input
2 2 2 0
YY
YY

Sample Output
YY

Data Constraint
30% : n <= 100.
60% : n <= 5000 , m <= 100.
100% : 1 <= n <= 30000 , 1 <= m <= 500. 0 <= p , q 且 p + q <= n.

//written by zzy

题目大意:

给你 n n n 个人的答案,其中有 p p p 个是全对, q q q 个是全错,求字典序最小的可能的正确答案。

题解:

将字符串从小到大排序,统计每个字符串的出现次数,(字符串哈希或 map)
要分三种情况讨论
p , q > 0 p,q>0 p,q>0 时,找到第一个出现次数等于全对答案数且反串出现次数等于全错答案数的字符串即为答案。
q > p = 0 q>p=0 q>p=0 时,从后往前找一个出现次数为0且反串出现次数等于全错答案数的字符串即为答案。
p = q = 0 p=q=0 p=q=0 时,dfs找个出现次数为0且反串出现次数为0的字符串即为答案。

#include
#include
#include
#include
#define N 30005
using namespace std;

int i,j,n,m,p,q,num;
string ans,s[N];

map<string,int> hash;

string rotate(string s) {
	string re="";
	for (int i=0;i<=m-1;i++)
	 if (s[i]=='N') re+='Y'; else re+='N';
	return re;
}

void dfs(int l,string s) {
	if (l==m) {
		if (hash[s]==0&&hash[rotate(s)]==0&&ans>s) ans=s;
		return; 
	}
	dfs(l+1,s+'N');
	dfs(l+1,s+'Y');
}

int main()
{
	scanf("%d%d%d%d\n",&n,&m,&p,&q);
	for (i=1;i<=n;i++) {
		cin>>s[i]; hash[s[i]]++;
	}
	sort(s+1,s+n+1);  
	if (p!=0) {
		for (i=1;i<=n;i++)
		 if (hash[s[i]]==p&&hash[rotate(s[i])]==q) {
		 	cout<<s[i]<<endl; return 0;
		 }
		 printf("-1");
	} else
	if (p==0&&q!=0) {
		for (i=n;i>=1;i--) 
		 if (hash[s[i]]==q) {
		 	cout<<rotate(s[i])<<endl; return 0;
		 }
		printf("-1");
	} else {
		for (i=1;i<=m;i++) ans+='Z';
	    if (p==0&&q==0) dfs(0,"");
	    if (ans[0]=='Z') printf("-1");
		else cout<<ans;
    }
}

你可能感兴趣的:(hash,离散,模拟)