正确答案 全国信息学奥林匹克联赛( ( NOIP2014) 复 赛 模拟题 Day1 长乐一中
【题目描述】
小 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.
長樂一中給出的解析:
30%: O(n ^ 2 * m)暴力判断。
100%: 很显然答案的可能性最多只有 n 种,所以我们将所有人的答案按字典序排序后枚举
将每个人的答案作为正确答案来进行判断。 由于是判断题, 若当前人的答案为正确答
案则零分者的答案也就确定了, 那么只需统计出这两种答案的人数判断是否满足题意
即可。这一步使用字符串哈希即可解决。
另外要注意 p = 0 和 p = q = 0 的情况。
長樂一中給出的正解代碼:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std; const int N = 3e4 + , M = 5e2 + , sed = , SED = , mod = , MOD = ;
int n, m, p, q, ans, hash[N], HASH[N];
int top, info[mod], nxt[N * ], fet[N * ], cnt[N * ];
struct node {
char s[M];
inline bool operator < (const node &b) const {
return strcmp(s, b.s) < ;
}
} a[N]; inline void Insert(const int &x, const int &y) {
for (int k = info[x]; k; k = nxt[k])
if (fet[k] == y) {
++cnt[k]; return ;
}
nxt[++top] = info[x]; info[x] = top;
fet[top] = y; cnt[top] = ;
return ;
} inline int Query(const int &x, const int &y) {
for (int k = info[x]; k; k = nxt[k])
if (fet[k] == y) return cnt[k];
return ;
} inline void Solve1() {
int tmp, TMP; ans = -;
for (int i = ; i < n; ++i) {
tmp = TMP = ;
for (int j = ; j < m; ++j) {
tmp = (tmp * sed + (a[i].s[j] == 'N')) % mod;
TMP = (TMP * SED + (a[i].s[j] == 'N')) % MOD;
}
hash[i] = tmp, HASH[i] = TMP;
Insert(tmp, TMP);
}
for (int i = ; i < n; ++i)
if (Query(hash[i], HASH[i]) == p) {
tmp = TMP = ;
for (int j = ; j < m; ++j) {
tmp = (tmp * sed + (a[i].s[j] == 'Y')) % mod;
TMP = (TMP * SED + (a[i].s[j] == 'Y')) % MOD;
}
if (Query(tmp, TMP) == q) {
ans = i; break;
}
}
if (ans != -) printf("%s\n", a[ans].s);
else puts("-1");
return ;
} char cur[M];
inline void Solve2() {
int tmp, TMP; ans = -;
for (int i = ; i < n; ++i) {
tmp = TMP = ;
for (int j = ; j < m; ++j) {
tmp = (tmp * sed + (a[i].s[j] == 'N')) % mod;
TMP = (TMP * SED + (a[i].s[j] == 'N')) % MOD;
}
hash[i] = tmp, HASH[i] = TMP;
Insert(tmp, TMP);
}
for (int i = n - ; i >= ; --i)
if (Query(hash[i], HASH[i]) == q) {
tmp = TMP = ;
for (int j = ; j < m; ++j) {
tmp = (tmp * sed + (a[i].s[j] == 'Y')) % mod;
TMP = (TMP * SED + (a[i].s[j] == 'Y')) % MOD;
}
if (Query(tmp, TMP) == p) {
ans = i; break;
}
}
if (ans != -) {
for (int i = ; i < m; ++i)
cur[i] = a[ans].s[i] == 'N' ? 'Y' : 'N';
printf("%s\n", cur);
}
else puts("-1");
return ;
} void Solve3() {
int tmp, TMP;
for (int i = ; i < n; ++i) {
tmp = TMP = ;
for (int j = ; j < m; ++j) {
tmp = (tmp * sed + (a[i].s[j] == 'N')) % mod;
TMP = (TMP * SED + (a[i].s[j] == 'N')) % MOD;
}
Insert(tmp, TMP);
tmp = TMP = ;
for (int j = ; j < m; ++j) {
tmp = (tmp * sed + (a[i].s[j] == 'Y')) % mod;
TMP = (TMP * SED + (a[i].s[j] == 'Y')) % MOD;
}
Insert(tmp, TMP);
}
bool flag = true;
for (int i = ; i < m; ++i) cur[i] = 'N';
do {
tmp = TMP = ;
for (int j = ; j < m; ++j) {
tmp = (tmp * sed + (cur[j] == 'N')) % mod;
TMP = (TMP * SED + (cur[j] == 'N')) % MOD;
}
if (Query(tmp, TMP) == ) {
flag = true; break;
}
flag = false;
for (int j = m - ; j >= ; --j)
if (cur[j] == 'Y') cur[j] = 'N';
else {
cur[j] = 'Y'; flag = true; break;
}
} while (flag);
if (flag) printf("%s\n", cur);
else puts("-1");
return ;
} int main() {
freopen("answer.in", "r", stdin);
freopen("answer.out", "w", stdout);
scanf("%d%d%d%d", &n, &m, &p, &q);
for (int i = ; i < n; ++i) scanf("%s", a[i].s);
sort(a, a + n);
if (p) Solve1();
else if (q) Solve2();
else Solve3();
fclose(stdin); fclose(stdout);
return ;
}
代碼實現:
#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,p,q,a,z=;
char ch[],cn[];
string st[];//儲存每個答案。
map <string,int> mm;//儲存每種答案出現的次數。
void part_1(){
for(int i=;i<n;i++){//順序枚舉。
if(mm[st[i]]==p){ //假如當前答案的出現數等於正解數,
for(int j=;j<m;j++){//ch中是這個答案的錯排。
if(st[i][j]=='N') ch[j]='Y';
else ch[j]='N';
}
if(mm[ch]==q){cout<<st[i]<<endl;return;}//並且它的錯排的出現數等於報零答案數,可以認為這是正解。
}
}
printf("-1\n");//如果沒有找到,即p,q不合法,輸出負一。
}
void part_2(){
for(int i=;i<n;i++){
if(mm[st[i]]==q){//如果當前答案的出現數等於報零答案數,
for(int j=;j<m;j++){
if(st[i][j]=='N') ch[j]='Y';
else ch[j]='N';
}
if(!mm[cn]){cout<<ch<<endl;return;}//並且它的錯排,即正解,沒有出現過,則它的錯排合法。
}
}
printf("-1\n");//對於數據,並無意義。
}
void part_3(){//正解和報零答案都沒有出現過,所以要捋一下全排列。
for(int i=;i<m;i++){
cn[i]='N';//從字典序排列時最前面的先拿出。
z*=;//z等於二的m次冪。
}
for(int i=;i<z/;i++){//小於z可以理解,因為這是一個類似01字串的字符串。
a=m-;cn[a]+='Y'-'N';
while(cn[a]==*'Y'-'N'&&a>){
cn[a--]='N';
cn[a]+='Y'-'N';
}//因為有錯排,所以是小於z/2。
for(int j=;j<m;j++){
if(cn[j]=='N') ch[j]='Y';
else ch[j]='N';
}
if(!mm[cn]&&!mm[ch]){cout<<cn<<endl;return;}//如果該排列即其錯排都為出現個,則該排列合法。
}
printf("-1\n");//對於數據,並無意義。
}
int main(){
freopen("answer.in","r",stdin);
freopen("answer.out","w",stdout);
scanf("%d%d%d%d",&n,&m,&p,&q);
for(int i=;i<n;i++){
scanf("%s",&ch);//一種比較簡單的讀入技巧,時間大概是直接cin流輸入的三分之一。
for(int j=;j<m;j++) st[i]+=ch[j];
++mm[st[i]];//記錄重新次數。
}
sort(st,st+n);//因為答案要按字典序輸出,所以排一下序。
if(p) part_1();
if(!p&&q) part_2();
if(!p&&!q) part_3();
return ;
}
吐槽一下,這個答案很多時候并並不正確。
正确答案 全国信息学奥林匹克联赛( ( NOIP2014) 复 赛 模拟题 Day1 长乐一中的更多相关文章
- 全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中
题目名称 正确答案 序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer. ...
- 全国信息学奥林匹克联赛(NOIP2014)复赛 模拟题Day2 长乐一中
题目名称 改造二叉树 数字对 交换 英文名称 binary pair swap 输入文件名 binary.in pair.in swap.in 输出文件名 binary.out pair.out sw ...
- 第二十四届全国青少年信息学奥林匹克联赛初赛 普及组C++语言试题
第二十四届全国青少年信息学奥林匹克联赛初赛 普及组C++语言试题 1.原题呈现 2.试题答案 3.题目解析 因博客园无法打出公式等,所以给你们几个小编推荐的链接去看看,在这里小编深感抱歉! https ...
- 巨坑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 ...
- 正确答案 [Hash/枚举]
正确答案 题目描述 小H与小Y刚刚参加完UOIP外卡组的初赛,就迫不及待的跑出考场对答案. "吔,我的答案和你都不一样!",小Y说道,"我们去找神犇们问答案吧" ...
- PMP全真模拟题真题試題含答案解析 2019年下半年PMP考試适用 PMP中文文对照试题 【香港台灣地區PMP考試也可用】
PMP全真模拟题真题试题 含答案解析 2019年下半年PMP考试适用 PMP中文文对照试题 [香港台灣地區PMP考試也可用]PMP全真模擬題真題試題 含答案解析 2019年下半年PMP考試适用 PMP ...
- 全国青少年信息学奥林匹克分区联赛(N)竞赛大纲
全国青少年信息学(计算机)奥林匹克分区联赛竞赛大纲 一.初赛内容与要求:(#表示普及组不涉及,以下同) 计算机的基本发展 诞生与发展 特点 在现代社会中的应用 计算机系统的基本组成 计算机的工作原理# ...
- java能不能自己写一个类叫java.lang.System/String正确答案
原文: http://www.wfuyu.com/php/22254.html 未做测试 ! 最近学习了下java类加载相干的知识.然后看到网上有1道面试题是 能不能自己写个类叫java.lang.S ...
- JS不用通过其他转换两个小数加减得到正确答案
之前写过一篇文章js比较两个属于float类型的小数,都需要通过某种函数转换下,太麻烦了,比如: 减法:10.2345-0.01=10.2245,这是正确的答案,但是当你做加法的时候就变了 加法:10 ...
随机推荐
- Enumeration 接口
Enumeration是遍历集合元素的一种方法. Enumeration中只有两个方法: 1.hasMoreElements() 测试此枚举是否包含更多的元素. 2.nextElement() 如 ...
- linux的简单网络配置
1,修改IP edit file: # if rh family system /etc/sysconfig/network-scripts/ifcfg-eth0 (eth0可能会是别的名字) # i ...
- 教学目标的表述方式──行为目标的ABCD表述法
教学目标应规定学生在教学活动结束后能表现出什么样的学业行为,并限定学生学习过程中知识.技能的获得和情感态度发展的层次.范围.方式及变化效果的量度.对每节课教学目标的准确表述,可以充分发挥教学目标在教学 ...
- 《Head First设计模式(中文版)》
<Head First设计模式(中文版)>共有14章,每章都介绍了几个设计模式,完整地涵盖了四人组版本全部23个设计模式.前言先介绍<Head First设计模式(中文版)>的 ...
- 重拾java系列一java基础(1)
前言,不知不觉,从接触java到工作至今已有两年的时间,突然感觉自己的基础知识还很薄弱,有些知识虽然知道,但是停留在表面上,没有深挖,或者实践过,感觉掌握的很肤浅,而且时间一长,就觉得忘记了,我觉得这 ...
- EventBus vs Otto vs LiteEventBus
http://blog.chengyunfeng.com/?p=449 http://litesuits.com/
- (spring-第4回【IoC基础篇】)spring基于注解的配置
基于XML的bean属性配置:bean的定义信息与bean的实现类是分离的. 基于注解的配置:bean的定义信息是通过在bean实现类上标注注解实现. 也就是说,加了注解,相当于在XML中配置了,一样 ...
- 使用Qemu调试内核
利用Qemu进行内核源码级调试 http://blog.csdn.net/gdt_a20/article/details/7231652 用Qemu调试Linux内核 http://blog.chin ...
- android手机连接PC无法正常安装驱动
工作当中我们经常会遇到Android手机连接PC的时候无法正确安装驱动,或者安装失败.当然找到正确的驱动文件时首选的解决方案,如果正确的驱动文件依旧无法安装成功我们可以打开我的电脑-->属性-- ...
- JAVA的第一个程序
关于下载安装环境变量的配置网上的教程已经很多了 . 下面附上第一个HelloWorld的代码 /** 这是我的第一个java程序 */ public class HelloWorld { public ...