【用膝盖写代码系列】(2):NOIP2011普及组复赛详解
来源:互联网 发布:英剧四级一部 知乎 编辑:程序博客网 时间:2024/04/29 11:32
这里是NOIP2011的急救现场,我已经准备好了救护车。
那么我们从第一题开始
第一题:数字反转
题意简述:给一个不超过10位的数(包括负号),输出这个数的反转。
(如:123,输出321)
陷阱提示:记得要预处理负号以及前导0
我对它的类型评估: 模拟
思路描述:这道题十分简单,用字符串读入,预处理负号,然后从后往前for,处理前导0,就可AC。
我的代码:
#include <cstdio>#include <cstring>int main(){ int i,j,n,m; char a[13]; scanf("%s",&a); int len = strlen(a); if(len == 1 && a[len-1] == 0) { printf("0"); return 0; } if(a[0] == '-') printf("-"); len--; // printf("a[len] = %c\n",a[len]); while(a[len] == '0') len--; for(i=len;i>=0;i--) if(a[i] >= '0' && a[i] <= '9') printf("%c",a[i]);}
洛谷原题:http://www.luogu.org/problem/show?pid=1307
第一题完。
第二题:统计单词数
(本人的内心:啊!!!!这是谁出的题目!拖出去大阿十遍!)
题目简述:给定一个单词以及一篇文章,求这个单词在文章的出现次数以及第一次出现的位置
陷阱提示:要注意全字匹配,不能单单截取单词的一部分!
我对它的类型评估:字符串操作、模拟
思路描述:这道题好坑啊TAT,主要原因是它的文章是有纯空格单词的…..这道题的思想就是:先把字母大小写统一(本题不区分大小写,所以要统一),然后枚举每一个文章中的单词,与原本的单词进行比较。
枚举的过程:枚举每一个文章中的字母,然后从当前字母A开始向后枚举所需求单词B的长度,然后A与B比较,如果完全相同,然后再判断单词A的前、后是否都是空格(否则有可能出现枚举一个单词一部分的情况),如果是第一次更新,就把答案设置为枚举时所循环的值(一般是i),此做法能AC、
我的代码
#include <cstdio>#include <cstring>#include <iostream>#include <cstdlib>using namespace std;int main(){ int i,j,n,m; char word[12]; char text[1000001]; //freopen("a.in","r",stdin); gets(word); gets(text); int lenw = strlen(word),lent = strlen(text); int count = 0,cur = -1; int sum=0; bool flag = true; for(i=0;i<lenw;i++) { if(word[i] >= 'a' && word[i] <= 'z') word[i] = word[i]&~(1<<5);//小写转大写 } for(i=0;i<lent;i++) { if(text[i] >= 'a' && text[i] <= 'z') text[i] = text[i]&~(1<<5);//同上 } for(i=0;i<=lent;i++){ for(j=0;j<lenw;j++){ if(text[i+j]!= word[j]) flag = false; } if(flag) { if((text[i-1] == ' ' && text[i+lenw] == ' ')|| i==0){ count++; if(cur==-1) { cur = i; } } } flag = true; } if(cur==-1) puts("-1"); else printf("%d %d",count,cur); return 0;}
洛谷原题:http://www.luogu.org/problem/show?pid=1308
第二题总结:每一道题都有一个陷阱,切记在考场上要考虑到可能出现的数据!
第二题完。
第三题:瑞士轮
题意简述:给定n个人的实力以及分数,每一次比赛都让相差一名的人进行比赛(第一与第二,第三与第四,以此类推),赢的人得1分,然后重新排名。先给出人数n*2,场数r,以及q,求r场后排名q的选手编号是多少
陷阱提示:此题用sort会TLE!
数据范围:对于100%的数据,
1 ≤ N ≤ 100,000,1 ≤ R ≤ 50,1 ≤ Q ≤ 2N,0 ≤
我对它的类型评估:模拟
*本题涉及函数:*merge
merge(数组A,A的结尾,数组B,B的结尾,输出数组C,交换函数)
这个函数的作用是合并数组A与数组B,若A、B是有序的,即完成一次归并排序。
思路描述:这道题其实就如题面描述一般进行模拟即可,记住每一次比赛模拟结束之后,记录一下成功者与失败者,最后用merge来合并(因为这两个数组一定有序)
我的代码
#include <cstdio>#include <algorithm>#include <queue>struct Player{ int score,num,val;}player[200002];bool cmp(Player a,Player b){ if(a.score == b.score) return a.num < b.num; else return a.score > b.score; }Player winner[200001],loser[200001];int main(){ int i,j,n,m,q,r,winner_count=0,loser_count=0; scanf("%d%d%d",&n,&r,&q); for(i=1;i<=n*2;i++){ scanf("%d",&player[i].score); player[i].num = i; } for(i=1;i<=n*2;i++) scanf("%d",&player[i].val); std::sort(player+1,player+1+(2*n),cmp); for(i=1;i<=r;i++){ winner_count = loser_count = 0; for(j=1;j<=n*2;j+=2){ if(player[j].val > player[j+1].val) { player[j].score++; winner[winner_count++] = player[j]; loser[loser_count++] = player[j+1]; } else{ player[j+1].score++; winner[winner_count++] = player[j+1]; loser[loser_count++] = player[j]; } } std::merge(winner,winner+winner_count,loser,loser+loser_count,player+1,cmp); } printf("%d",player[q].num);}
洛谷原题:http://www.luogu.org/problem/show?pid=1309
第三题完。
第四题:表达式的值
题意简述:
对于1 位二进制变量定义两种运算:
运算的优先级是:
先计算括号内的,再计算括号外的。
“× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算。例如:计算表达式A⊕B × C时,先计算 B × C,其结果再与 A 做⊕运算。
现给定一个未完成的表达式,例如+(*_),请你在横线处填入数字0 或者1 ,请问有多少种填法可以使得表达式的值为0 。
陷阱提示:无
我对它的类型评估:栈、动态规划
思路描述:
这道题是我做过最难的NOIP题目。
这道题的步骤很简单:
①:将式子从+(x)的形式变成的带有空的形式
②:将式子从中缀表达式化作后缀表达式
③:进行动态规划
状态转移方程:
设f[i][0]表示第i个空,能填0,f[i][1]表示第i个空,能填1
那么转移方程就出来了:
switch(w_c[i]){ case '+':{ f[top-1][1] = (f[top][0] * f[top-1][1] + f[top][1] * f[top-1][0] + f[top][1] * f[top-1][1])%10007; f[top-1][0] = (f[top][0] * f[top-1][0]) % 10007; break; } case '*':{ f[top-1][0] = (f[top][0] * f[top-1][1] + f[top][1] * f[top-1][0] + f[top][0] * f[top-1][0])%10007; f[top-1][1] = (f[top][1] * f[top-1][1]) % 10007; break; } }
我的代码:
#include <cstdio>#include <stack> #include <iostream>using namespace std;int i,j,n,m;string s,w_c;char str[100001],first[3] = {'(','+','*'};int f[100001][2];stack<char> op; int OPS(char a){ int i; for(i=0;i<3;i++){ if(a == first[i]) return i; } return -1; } inline void ChangeS(){ int i; for(i=0;i<n;i++){ if(str[i] == '(') s.push_back(str[i]); else if(str[i] == ')' && str[i-1] != ')') s+="_)"; else if(str[i]!=')' && str[i-1] != ')') { s.push_back('_'); s.push_back(str[i]); } else s.push_back(str[i]); } if(s.at(s.size()-1)!=')') s.push_back('_'); } inline void ChangeE(){ size_t i; char t; for(i=0;i<s.size();i++){ t = s.at(i); if(t == '_') w_c.push_back(t); else{ if(t!=')'){ if(t=='(') op.push(t); else{ if(op.empty()) op.push(t); else{ while((!op.empty())&& OPS(op.top())>=OPS(t)) { w_c.push_back(op.top()); op.pop(); } op.push(t); } } } else{ while((!op.empty()) && op.top()!='('){ w_c.push_back(op.top()); op.pop(); } op.pop(); } } } while(!op.empty()){ w_c.push_back(op.top()); op.pop(); }} void work(){ size_t i,top(0); size_t l = w_c.size(); for(i=0;i<l;i++) { if(w_c[i] == '_'){ f[top][0] = f[top][1] = 1; top++; } else{ --top; switch(w_c[i]){ case '+':{ f[top-1][1] = (f[top][0] * f[top-1][1] + f[top][1] * f[top-1][0] + f[top][1] * f[top-1][1])%10007; f[top-1][0] = (f[top][0] * f[top-1][0]) % 10007; break; } case '*':{ f[top-1][0] = (f[top][0] * f[top-1][1] + f[top][1] * f[top-1][0] + f[top][0] * f[top-1][0])%10007; f[top-1][1] = (f[top][1] * f[top-1][1]) % 10007; break; } } } } printf("%d",f[top-1][0]);}int main(){ scanf("%d",&n); scanf("%s",str); ChangeS(); ChangeE(); //for(i=0;i<=w_c.length();i++) printf("%c",w_c[i]); work(); return 0;}
洛谷原题:http://www.luogu.org/problem/show?pid=1310
第四题完。
各位再见,我开救护车去飙车了88
(很抱歉,最后一题的代码有一些问题,现在已修正。)
- 【用膝盖写代码系列】(2):NOIP2011普及组复赛题目详解
- 【用膝盖写代码系列】(2):NOIP2011普及组复赛详解
- 【用膝盖写代码系列】(1):NOIP2010普及组复赛详解
- 【用膝盖写代码系列】(4):NOIP2014普及组复赛详解
- 【用膝盖写代码系列】(5):NOIP2013普及组复赛详解
- 【用膝盖写代码系列】(3):NOIP2012普及组题目详解
- 【蒻爆了的NOIP系列--普及组复赛】(2)NOIP2011普及组复赛题解
- Noip2011普及组
- NOIP2011 普及组题解
- 【蒻爆了的NOIP系列--普及组复赛】(1)NOIP2010普及组复赛题解
- 【蒻爆了的NOIP系列--普及组复赛】(4)NOIP2013普及组复赛题解
- 【蒻爆了的NOIP系列--普及组复赛】(5)NOIP2014普及组复赛题解
- 【蒻爆了的NOIP系列--普及组复赛】(6)NOIP2015普及组复赛题解
- 【蒻爆了的NOIP系列--普及组复赛】(3)NOIP2012普及组复赛题解
- 【蒻爆了的NOIP系列--普及组复赛】(7)NOIP2016普及组复赛题解
- noip2016普及组复赛
- NOIP2011普及组 瑞士轮
- 【NOIP2011普及组】瑞士轮
- TCP和UDP有什么区别
- 简单描述Oracle物化视图日志
- android控件——ImageView
- 抽象类型
- 【用膝盖写代码系列】(5):NOIP2013普及组复赛详解
- 【用膝盖写代码系列】(2):NOIP2011普及组复赛详解
- IO流的学习笔记
- 刚刚装了ubuntu,遇到error:file /boot/grub/i386-pc /normal.mod not found
- wifi网络的判断
- OSG环境下GLSL实现几何着色器的纹理采样
- PAT 1061Insert or Merge (25)
- 集合框架
- linux设备驱动day3-驱动介绍,注册和加载实现
- operator ++