• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Retarded_ZY
博客园    首页    新随笔    联系   管理    订阅  订阅

正确答案

正确答案

题目描述

小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.

来源

八校长乐day1

solution:

看到m有500,n有30000,时间复杂度O(n^2)肯定是不行的,只能是O(nm)的。这就意味着要查找一种答案出现了几次不能枚举每一个人,得存下来,最多花费O(lg n)的时间查询。于是需要给每一个答案进行编号,很自然地想到了Hash。最多会有n个答案,不能直接用数组存,因为想要开的下,p就得比较小,由于生日悖论,会有很多冲突,且是单Hash,很容易出错,这太不靠谱。其实p很大的话,实测证明单Hash也可以,但还是开不下数组的,还不如双Hash保险一点。一个比较好的方法是将每一对Hash值捆在一起,排序,查找时候二分一下就好了,查询时间复杂度O(lg n),可以的。当然,像我这样的C++选手是不愿意这样写的,我很懒的。可以用set和自带的二分,这样会方便的多,然而最方便的肯定是map,直接当数组用,看似10^18次的数组,实际上只有O(n)的空间,神器啊!不过map是用红黑树写的,所以时间复杂度还是O(lg n),且常数因子大,速度会慢一些。好在这道题目并不怕TLE,可以放心的用。这样做法就很简单了,枚举每一个答案,计算它的Hash值,得到它出现的次数,判断是否等于p,如果是,再将它取反(N变Y,Y变N),计算Hash值,判断是否等于q,如果也是,则将这个原串与答案比较,取字典序最小的。当心p、q可以是0,要特殊处理,特别是p=q=0的时候,直接暴力枚举就好了,O(n)的。下面是代码,用了STL还是很长……

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<cstdlib>
  6 #include<cstring>
  7 #include<map>
  8 using namespace std;
  9 typedef long long ll;
 10 ll read(){
 11     ll ans=0;
 12     char ch=getchar(),last=' ';
 13     while(ch>'9'||ch<'0'){
 14         last=ch;
 15         ch=getchar();
 16     }
 17     while(ch<='9'&&ch>='0'){
 18         ans=ans*10+ch-'0';
 19         ch=getchar();
 20     }
 21     if(last=='-')
 22         ans=-ans;
 23     return ans;
 24 }
 25 map<ll,map<ll,int> > a;
 26 int n,m,p,q;
 27 ll x,y,ans,xx,yy,p1,p2;
 28 char st[30005][505],ac[505];
 29 bool flag;
 30 bool ok(char* a,char* b){
 31     for(int i=0;i<m;i++)
 32         if(a[i]!=b[i])
 33             return a[i]<b[i];
 34     return false;
 35 }
 36 int main(){
 37     p1=(ll)1000000007;
 38     p2=(ll)1000000003;
 39     n=read();
 40     m=read();
 41     p=read();
 42     q=read();
 43     for(int i=1;i<=n;i++){
 44         scanf("%s",st[i]);
 45         x=y=0;
 46         for(int j=0;j<m;j++){
 47             x=(x+x)%p1;
 48             y=(y+y)%p2;
 49             if(st[i][j]=='Y'){
 50                 x=(x+(ll)1)%p1;
 51                 y=(y+(ll)1)%p2;
 52             }
 53         }
 54         a[x][y]++;
 55     }
 56     if(p==0&&q==0){
 57         for(int i=0;i<m;i++)
 58             ac[i]='N';
 59         ac[m-1]='Y';
 60         while(1){
 61             x=y=0;
 62             for(int j=0;j<m;j++){
 63                 x=(x+x)%p1;
 64                 y=(y+y)%p2;
 65                 if(ac[j]=='Y'){
 66                     x=(x+(ll)1)%p1;
 67                     y=(y+(ll)1)%p2;
 68                 }
 69             }
 70             xx=yy=0;
 71             for(int j=0;j<m;j++){
 72                 xx=(xx+xx)%p1;
 73                 yy=(yy+yy)%p2;
 74                 if(ac[j]=='N'){
 75                     xx=(xx+(ll)1)%p1;
 76                     yy=(yy+(ll)1)%p2;
 77                 }
 78             }
 79             if(a[x][y]==0&&a[xx][yy]==0){
 80                 flag=true;
 81                 break;
 82             }
 83             int k=-1;
 84             for(int j=m-1;j>=0;j--)
 85                 if(ac[j]=='N'){
 86                     k=j;
 87                     break;
 88                 }
 89             ac[k]='Y';
 90             for(int j=k+1;j<m;j++)
 91                 ac[j]='N';  
 92         }
 93         if(flag){
 94             for(int j=0;j<m;j++)
 95                 printf("%c",ac[j]);
 96             printf("\n");
 97         }
 98         else
 99             printf("-1\n");
100         return 0;
101     }
102     if(p==0){
103         for(int i=1;i<=n;i++){
104             x=y=0;
105             for(int j=0;j<m;j++){
106                 x=(x+x)%p1;
107                 y=(y+y)%p2;
108                 if(st[i][j]=='Y'){
109                     x=(x+1)%p1;
110                     y=(y+1)%p2;
111                 }
112             }
113             xx=yy=0;
114             for(int j=0;j<m;j++){
115                 xx=(xx+xx)%p1;
116                 yy=(yy+yy)%p2;
117                 if(st[i][j]=='N'){
118                     xx=(xx+1)%p1;
119                     yy=(yy+1)%p2;
120                 }
121             }
122             if(a[x][y]==q&&a[xx][yy]==p){
123                 ans++;
124                 if(ans==1||ok(ac,st[i]))
125                     for(int j=0;j<m;j++)
126                         ac[j]=st[i][j];
127             }
128         }
129         if(ans){
130             for(int j=0;j<m;j++)
131                 printf("%c",ac[j]=='Y'?'N':'Y');
132             printf("\n");
133         }
134         return 0;
135     }
136     if(q==0){
137         for(int i=1;i<=n;i++){
138             x=y=0;
139             for(int j=0;j<m;j++){
140                 x=(x+x)%p1;
141                 y=(y+y)%p2;
142                 if(st[i][j]=='Y'){
143                     x=(x+1)%p1;
144                     y=(y+1)%p2;
145                 }
146             }
147             xx=yy=0;
148             for(int j=0;j<m;j++){
149                 xx=(xx+xx)%p1;
150                 yy=(yy+yy)%p2;
151                 if(st[i][j]=='N'){
152                     xx=(xx+1)%p1;
153                     yy=(yy+1)%p2;
154                 }
155             }
156             if(a[x][y]==p&&a[xx][yy]==q){
157                 ans++;
158                 if(ans==1||ok(st[i],ac))
159                     for(int j=0;j<m;j++)
160                         ac[j]=st[i][j];
161             }
162         }
163         if(ans){
164             for(int j=0;j<m;j++)
165                 printf("%c",ac[j]);
166             printf("\n");
167         }
168         return 0;
169     }
170     for(int i=1;i<=n;i++){
171         x=y=0;
172         for(int j=0;j<m;j++){
173             x=(x+x)%p1;
174             y=(y+y)%p2;
175             if(st[i][j]=='Y'){
176                 x=(x+1)%p1;
177                 y=(y+1)%p2;
178             }
179         }
180         xx=yy=0;
181         for(int j=0;j<m;j++){
182             xx=(xx+xx)%p1;
183             yy=(yy+yy)%p2;
184             if(st[i][j]=='N'){
185                 xx=(xx+1)%p1;
186                 yy=(yy+1)%p2;
187             }
188         }
189         if(a[x][y]==p&&a[xx][yy]==q){
190             ans++;
191             if(ans==1||ok(st[i],ac))
192                 for(int j=0;j<m;j++)
193                     ac[j]=st[i][j];
194         }
195     }
196     if(ans){
197         for(int j=0;j<m;j++)
198             printf("%c",ac[j]);
199         printf("\n");
200     }
201     else
202         printf("-1\n");
203     return 0;
204 }

 

posted @ 2017-07-15 09:33  Retarded_ZY  阅读(565)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3