题目描述
小H与小Y刚刚参加完UOIP外卡组的初赛,就迫不及待的跑出考场对答案。
“吔,我的答案和你都不一样!”,小Y说道,”我们去找神犇们问答案吧”。
外卡组试卷中共有m道判断题,小H与小Y一共从其他n个神犇那问了答案。之后又从小G那里得知,这n个神犇中有p个考了满分,q个考了零分,其他神犇不为满分或零分。这可让小Y与小H犯了难。你能帮助他们还原出标准答案吗?如有多解则输出字典序最小的那个。无解输出-1。
题目解析
首先用mapmapmap记录每一个字符串出现的次数f1f1f1,然后把每一个字符串取反也记录一下出现次数f2f2f2并排序。
分几种情况:
1、当p≠0p\neq0p=0时,比较一下就可以了。
2、如果p=0,q=0p=0,q=0p=0,q=0,搜出第一个没有出现且取反后没有出现的字符串,即第一个f1[s]=0f1[s]=0f1[s]=0且f2[s]=0f2[s]=0f2[s]=0的sss。因为要求字典序最小。
3、如果p=0,q≠0p=0,q\neq0p=0,q=0,那么就枚举每一个sss,如果f2[s]=0f2[s]=0f2[s]=0,那么就将sss取反输出即可。
代码
#include<bits/stdc++.h>
#define N 30005
using namespace std;
int n,m,p,q;
string s[N],s0;
map<string,int> f1,f2;
bool flag;
void dfs(int x,string ss)
{
if(x>m)
{
if(f1[ss]==p&&f2[ss]==q) cout<<ss,flag=1;
return;
}
dfs(x+1,ss+'N');
if(flag) return;
dfs(x+1,ss+'Y');
}
int main()
{
cin>>n>>m>>p>>q;
for(int i=1;i<=n;i++)
{
cin>>s[i];s0=s[i];
f1[s0]++;
for(int j=0;j<m;j++)
s0[j]=(s0[j]=='Y'?'N':'Y');
f2[s0]++;
}
sort(s+1,s+1+n);
if(!p&&!q)
{
dfs(1,"");
if(!flag) printf("-1");
return 0;
}
if(!p)
{
for(int i=1;i<=n;i++)
if(f1[s[i]]==q)
{
for(int j=0;j<m;j++)
cout<<(s[i][j]=='Y'?'N':'Y');
return 0;
}
printf("-1");
return 0;
}
for(int i=1;i<=n;i++)
if(f1[s[i]]==p&&f2[s[i]]==q)
{
cout<<s[i];
return 0;
}
printf("-1");
}