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

題目大意:

給你 nn 個人的答案,其中有 pp 個是全對, qq 個是全錯,求字典序最小的可能的正確答案。

題解:

將字符串從小到大排序,統計每個字符串的出現次數,(字符串哈希或 map)
要分三種情況討論
p,q>0p,q>0 時,找到第一個出現次數等於全對答案數且反串出現次數等於全錯答案數的字符串即爲答案。
q>p=0q>p=0 時,從後往前找一個出現次數爲0且反串出現次數等於全錯答案數的字符串即爲答案。
p=q=0p=q=0 時,dfs找個出現次數爲0且反串出現次數爲0的字符串即爲答案。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章