@IOU
2018-06-09T11:24:26.000000Z
字数 4515
阅读 1044
哈希
MAP
trie树
考试
网盘里有。
【题目描述】
小 H 与小 Y 刚刚参加完 UOIP 外卡组的初赛,就迫不及待的跑出考场对答案。
“吔,我的答案和你都不一样!”,小 Y 说道,”我们去找神犇们问答案吧”。
外卡组试卷中共有 m 道判断题,小 H 与小 Y 一共从其他 n 个神犇那问了答案。之后又
从小 G 那里得知,这 n 个神犇中有 p 个考了满分, q 个考了零分,其他神犇不为满分或零分。
这可让小 Y 与小 H 犯了难。你能帮助他们还原出标准答案吗?如有多解则输出字典序最小
的那个。无解输出-1。
【输入格式】
第一行四个整数 n, m, p, q,意义如上描述。
接下来 n 行,每一行 m 个字符’N’或’Y’,表示这题这个神犇的答案。
【输出格式】
仅一行,一个长度为 m 的字符串或是-1。
【样例输入】
2 2 2 0
YY
YY
【样例输出】
YY
【数据范围】
30% : n <= 100.
60% : n <= 5000 , m <= 100.
100% : 1 <= n <= 30000 , 1 <= m <= 500. 0 <= p , q 且 p + q <= n.
map和unordered_map的区别
map是个好东西。看个例子就很容易懂了。
map<string,int> h;
char str[25],tar[25];
for(int i=1;i<=n;i++)scanf("%s",str),h[str]++;
cin>>tar;
cout<<h[tar];
这段程序就是求tar这个字符串在之前输入的字符串中的出现次数。其实和字符串hash差不多。
这道题其实分三种情况讨论:
1.p!=0&&q!=0,就是让你选一种出现次数为p次,把它取反的字串出现q次,其实就和上面这个例子差不多,改一下就好。
2.p=0&&q!=0,一样的道理,找一个字串出现q次,把它取反的字串没有出现过,那把它取反的序列就是答案。
3.p=0&&q=0,那就从字典序最小的开始枚举,枚举2n+1次,一定可以得到一个不管是自己还是它的反序列都没有出现过的序列,最先找到的就是答案。
还有要注意,枚举序列的时候要先排序,这样确保找到的第一个字典序最小,可以直接break掉。
那么放在这道题复杂度应该是也就是30000×500×15=225 000 000好像是超过了的。。但是可以水过去的。。
判断方法改一下,预处理复杂度,询问的时候是的,因为要枚举n此,查询是的。但是排序的时候还是要,所以总的复杂度和map是一样的。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
string s[30005],ss,sss;
int main()
{
//freopen("answer.in","r",stdin);
//freopen("answer.out","w",stdout);
int n,mm,p,q;cin>>n>>mm>>p>>q;
map<string,int> m;
for(int i=1;i<=n;i++)cin>>s[i],m[s[i]]++;
sort(s+1,s+n+1);
if(p!=0)
{
for(int i=1;i<=n;i++)
{
ss.clear();
for(int j=0;j<mm;j++)ss.push_back((s[i][j]!='Y')?'Y':'N');
if(p==m[s[i]]&&q==m[ss]){cout<<s[i];return 0;}
}
}
else if(q!=0)
{
for(int i=1;i<=n;i++)
{
ss.clear();
for(int j=0;j<mm;j++)ss.push_back((s[i][j]!='Y')?'Y':'N');
if(q==m[s[i]]&&p==m[ss]){cout<<ss;return 0;}
}
}
else
{
for(int i=0;i<=2*n;i++)
{
ss.clear();
for(int j=0;j<mm;j++)ss.push_back('N');
int t=i,k=-1;
while(t){k++;if(t%2)ss[mm-k]='Y';t/=2;}
sss=ss;
for(int j=0;j<mm;j++)sss[j]=(ss[j]!='Y')?'Y':'N';
if(m[ss]==0&&m[sss]==0){cout<<ss;return 0;}
}
}
cout<<-1;
return 0;
}
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<string>
#define mod 12345678
using namespace std;
string ss,sss;
int hash[12345679],num[30005];
int n,mm,p,q;
struct node
{
int id,h1,h2;
char s[505];
bool operator <(node x)const
{
return strcmp(s,x.s)<0;
}
void h()
{
int base=1,sum=0;
for(int j=0;j<mm;j++)
{
int w=(s[j]=='Y')?1:0;
sum+=base*w;sum%=mod;
base*=2;base%=mod;
}
h1=sum;base=1,sum=0;
for(int j=0;j<mm;j++)
{
int w=(s[j]!='Y')?1:0;
sum+=base*w;sum%=mod;
base*=2;base%=mod;
}
h2=sum;
}
}f[30005];
int main()
{
//freopen("answer.in","r",stdin);
//freopen("answer.out","w",stdout);
cin>>n>>mm>>p>>q;
for(int i=1;i<=n;i++)
{
scanf("%s",f[i].s);
f[i].h();hash[f[i].h1]++;
}
sort(f+1,f+n+1);
if(p!=0)
{
for(int i=1;i<=n;i++)
if(p==hash[f[i].h1]&&q==hash[f[i].h2]){cout<<f[i].s;return 0;}
}
else if(q!=0)
{
for(int i=1;i<=n;i++)
{
if(q==hash[f[i].h1]&&p==hash[f[i].h2])
{for(int j=0;j<mm;j++)printf("%c",((f[i].s[j]=='Y')?'N':'Y'));return 0;}
}
}
else
{
for(int i=0;i<=2*n;i++)
{
node x;memset(x.s,0,sizeof(x.s));
for(int j=0;j<mm;j++)x.s[j]='N';int t=i,k=-1;
while(t){k++;if(t%2)x.s[mm-k]='Y';t/=2;}
x.h();//cout<<hash[x.h1]<<" "<<hash[x.h2]<<endl;
if(hash[x.h1]==0&&hash[x.h2]==0){cout<<x.s;return 0;}
}
}
cout<<-1;
return 0;
}
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<string>
#define maxn 15000005
using namespace std;
int n,mm,p,q,ch[maxn][2],rt,end[maxn],cnt=1;
char f[30005][505],rec[505];
void insert(char *s)
{
int now=1;
for(int i=0;i<mm;i++)
{
int k=s[i]=='Y';
if(!ch[now][k])ch[now][k]=++cnt;
now=ch[now][k];end[now]++;
}
}
int query(char *s)
{
int now=1;
for(int i=0;i<mm;i++)
{
int k=s[i]=='Y';
if(!ch[now][k])return 0;
now=ch[now][k];
}
return end[now];
}
int query2(char *s)
{
int now=1;
for(int i=0;i<mm;i++)
{
int k=s[i]!='Y';
if(!ch[now][k])return 0;
now=ch[now][k];
}
return end[now];
}
void dfs(int x1,int x2,int k)
{
if(k==mm)
{
if(p==end[x1]&&q==end[x2]){cout<<rec;exit(0);}
return;
}
if(ch[x1][0])rec[k]='N',dfs(ch[x1][0],ch[x2][1],k+1);
if(ch[x1][1])rec[k]='Y',dfs(ch[x1][1],ch[x2][0],k+1);
}
void dfs2(int x1,int x2,int k)
{
if(k==mm)
{
if(q==end[x1]&&p==end[x2])
{for(int j=0;j<mm;j++)printf("%c",((rec[j]=='Y')?'N':'Y'));exit(0);}
return;
}
if(ch[x1][1])rec[k]='Y',dfs2(ch[x1][1],ch[x2][0],k+1);
if(ch[x1][0])rec[k]='N',dfs2(ch[x1][0],ch[x2][1],k+1);
}
int main()
{
//freopen("answer.in","r",stdin);
//freopen("answer.out","w",stdout);
cin>>n>>mm>>p>>q;
for(int i=1;i<=n;i++)
{
scanf("%s",f[i]);
insert(f[i]);
}
if(p!=0)
dfs(1,1,0);
else if(q!=0)
dfs2(1,1,0);
else
{
for(int i=0;i<=2*n;i++)
{
char s[505];
memset(s,0,sizeof(s));
for(int j=0;j<mm;j++)s[j]='N';int t=i,k=0;
while(t){k++;if(t%2)s[mm-k]='Y';t/=2;}
//cout<<i<<" "<<s<<" "<<query(s)<<" "<<query2(s)<<endl;
if(query(s)==0&&query2(s)==0){cout<<s;return 0;}
}
}
cout<<-1;
return 0;
}