正确答案

题目描述

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

题解

这道题在我看来是需要特判的恶心细节题,据说是一道noip模拟赛的题目

看到这道题目最开始的思路,把所有的答案hash一下,并把它们取反(即Y变N,N变Y),在hash一下,然后把每个答案都当做满分答案来做,因为只有Y和N两种答案,知道满分答案就能知道0分答案,统计一下这两种答案的个数是否满足题目所给的p和q,这里我用的是multiset,可重集合,直接计算元素个数,时间复杂度\(O(logn+szie),size\)是所查找元素的个数.

但是这样直接交的话只有60+左右,因为我们并没有考虑满分答案等于0的情况,其实这也很简单,就把所有答案都当成0分答案来做,像上面一样,只是反了过来,加上这个特判80+左右

最后还需要特判一下p和q都等于0的情况,这时我们直接深搜即可,因为要求字典序最小,我们就先搜N再搜Y,遇到第一个可行解直接输出并退出程序

  1. #include<bits/stdc++.h>
  2. #define Min(a,b) (a)<(b)?(a):(b)
  3. #define Max(a,b) (a)>(b)?(a):(b)
  4. #define in(i) (i=read())
  5. using namespace std;
  6. int read() {
  7. int ans=0,f=1; char i=getchar();
  8. while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
  9. while(i>='0' && i<='9') {ans=(ans<<1)+(ans<<3)+i-'0'; i=getchar();}
  10. return ans*f;
  11. }
  12. multiset<int>t;
  13. int n,m,p,q;
  14. int base=3,mod=1e9+7;
  15. struct str {
  16. int v;
  17. char s[510];
  18. }ans;
  19. char s[30010][510],ac[30010];
  20. int Hash[30010],Hash2[30010],len[30010];
  21. void dfs(int len) {
  22. if(len==m) {
  23. int sum1=0,sum2=0;
  24. for(int i=1;i<=m;i++) {
  25. sum1=(sum1*base%mod+(ac[i]=='N'))%mod;
  26. sum2=(sum2%base%mod+(ac[i]=='Y'))%mod;
  27. }
  28. if(!t.count(sum1) && !t.count(sum2)) {
  29. for(int i=1;i<=m;i++) printf("%c",ac[i]);
  30. puts(""),exit(0);
  31. }
  32. return;
  33. }
  34. ac[len+1]='N'; dfs(len+1);
  35. ac[len+1]='Y'; dfs(len+1);
  36. }
  37. int main()
  38. {
  39. ans.v=0; in(n); in(m); in(p); in(q);
  40. for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
  41. for(int i=1;i<=n;i++) {
  42. string po; len[i]=strlen(s[i]+1);
  43. for(int j=1;j<=len[i];j++) {
  44. Hash[i]=(Hash[i]*base%mod+(s[i][j]=='Y'))%mod;
  45. po+=(s[i][j]=='Y'?'N':'Y');
  46. Hash2[i]=(Hash2[i]*base%mod+(po[j-1]=='Y'))%mod;
  47. }
  48. }
  49. if(!p && !q) {
  50. for(int i=1;i<=n;i++) t.insert(Hash[i]),t.insert(Hash2[i]);
  51. dfs(0); cout<<-1<<endl;
  52. return 0;
  53. }
  54. else if(!p && q) {
  55. for(int i=1;i<=n;i++) t.insert(Hash2[i]);
  56. for(int i=1;i<=n;i++) {
  57. if(!t.count(Hash[i]) && t.count(Hash2[i])==q) {
  58. if(ans.v==0 || ans.v>Hash2[i]) {
  59. for(int j=0;j<len[i];j++) ans.s[j]=(s[i][j+1]=='Y'?'N':'Y');
  60. ans.v=Hash2[i];
  61. }
  62. }
  63. }
  64. if(ans.v!=0) cout<<ans.s<<endl;
  65. else cout<<-1<<endl;
  66. return 0;
  67. }
  68. else {
  69. for(int i=1;i<=n;i++) t.insert(Hash[i]);
  70. for(int i=1;i<=n;i++) {
  71. if(t.count(Hash2[i])==q && t.count(Hash[i])==p) {
  72. if(ans.v==0 || ans.v>Hash[i]) {
  73. for(int j=0;j<len[i];j++) ans.s[j]=s[i][j+1];
  74. ans.v=Hash[i];
  75. }
  76. }
  77. }
  78. if(ans.v!=0) cout<<ans.s<<endl;
  79. else cout<<-1<<endl;
  80. return 0;
  81. }
  82. }

博主自认为代码算比较短的了,我看网上其他的题解一个个分分钟一两百行上下啊

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/

正确答案 [Hash/枚举]的更多相关文章

  1. 正确答案 全国信息学奥林匹克联赛( ( NOIP2014) 复 赛 模拟题 Day1 长乐一中

    [题目描述]小 H 与小 Y 刚刚参加完 UOIP 外卡组的初赛,就迫不及待的跑出考场对答案."吔,我的答案和你都不一样!",小 Y 说道,"我们去找神犇们问答案吧&qu ...

  2. 巨坑npm run dev 报错 终于找到正确答案 Error: EPERM: operation not permitted, open '/data/public/build/css/add.p

    Windows10环境 npm run dev 报错  终于找到正确答案 Error: EPERM: operation not permitted, open '/data/public/build ...

  3. ios高效开发-正确的使用枚举(Enum)

    前言 Enum,也就是枚举,从C语言开始就有了,C++.Java.Objective-C.Swift这些语言,当然都有对应的枚举类型,功能可能有多有少,但是最核心的还是一个—规范的定义代码中的状态.选 ...

  4. java能不能自己写一个类叫java.lang.System/String正确答案

    原文: http://www.wfuyu.com/php/22254.html 未做测试 ! 最近学习了下java类加载相干的知识.然后看到网上有1道面试题是 能不能自己写个类叫java.lang.S ...

  5. JS不用通过其他转换两个小数加减得到正确答案

    之前写过一篇文章js比较两个属于float类型的小数,都需要通过某种函数转换下,太麻烦了,比如: 减法:10.2345-0.01=10.2245,这是正确的答案,但是当你做加法的时候就变了 加法:10 ...

  6. poj2456 二分逼近寻找正确答案

    Aggressive cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10078   Accepted: 4988 ...

  7. Wannafly模拟赛 A.矩阵(二分答案+hash)

    矩阵 时间限制:1秒 空间限制:131072K 题目描述 给出一个n * m的矩阵.让你从中发现一个最大的正方形.使得这样子的正方形在矩阵中出现了至少两次.输出最大正方形的边长. 输入描述: 第一行两 ...

  8. BZOJ1014[JSOI2008]火星人——非旋转treap+二分答案+hash

    题目描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 ...

  9. B1567 [JSOI2008]Blue Mary的战役地图 二分答案+hash

    一开始以为是dp,后来看了一下标签...二分答案?之前也想过,但是没往下想,然后之后的算法就顺理成章,先求出第一个地图的所有子矩阵的hash值,然后求第二个,在上一个地图例二分查找,然后就没了. 算法 ...

随机推荐

  1. python应用:TXT文件的读写

    python读写TXT文件不需要导入包 python中常用的读写方式: 文件打开模式 描述 r 以只读模式打开文件,并将文件指针指向文件头:如果文件不存在会报错 w 以只写模式打开文件,并将文件指针指 ...

  2. UVA - 12230

    #include <bits/stdc++.h> using namespace std; int n; double d; double p,l,v,ret,sum; ; /* 村庄A, ...

  3. matlab-罗曼诺夫斯基准则剔除粗大值

    罗曼诺夫斯基准则原理  罗曼诺夫斯基准则又称 t检验准则,其特点是首先删除一个可疑的的测得值,然后按 t分布检验被剔除的测量值是否含有粗大误差 罗曼诺夫斯基准则  1)选取合适的显著度a,选择合适的数 ...

  4. BFS 队列

    Plague Inc. is a famous game, which player develop virus to ruin the world. JSZKC wants to model thi ...

  5. 纯js实现复制内容到剪切板

    下面的方法可以完美实现: 复制指定input 或者 textarea中的内容: 指定非输入框元素中的内容 代码如下: function copyToClipboard(elem) { // creat ...

  6. SVN 使用时的小错误

    在使用SVN的时候总是出现一些小问题,今天又出现了一个,诶,分享一下吧!  Error:(个人文件夹名http://www.qdjhu.com/anli_xq/f_wancheng.php)  is ...

  7. 【廖雪峰老师python教程】——filter/sorted

    filter Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次作用于每个元素,然 ...

  8. 多个excel合并(excel2007)

    1.新建一个空的excel文件,在需要合并的目录下. 2.右键点击sheet1,点击查看代码 3.执行此段代码 Sub 合并当前目录下所有工作簿的全部工作表() Dim MyPath, MyName, ...

  9. python终极篇 --- django 初识

    1. 下载: 命令行: pip install django==1.11.15 pip install -i 源 django==1.11.15 pycharm settings 解释器 点+号 输入 ...

  10. 阿里云SLB漏选“健康检查正常的http状态码”导致url重定向失败问题处理

    背景:           一客户将线下电商网站迁移到阿里云上,公网出口使用阿里云SLB,SLB后端实例为ECS(webserver)web服务使用nginx.后端APP服务器使用了tomcat:to ...