第二次上机赛解题报告及标程
来源:互联网 发布:p2p网络借贷入罪 编辑:程序博客网 时间:2024/06/10 13:06
此次上机,起码从board上看要比第一次好了许多……虽然距离理想状态还是差了一些……
渣诚写的验题标程都是非STL的,有时间我会放上来……现在的标程STL居多先凑合看下= =
A. Payment
有点后悔把这道题放在第一道,以至于这道唯一和数据结构无关的题目让大多数人煎熬了好久……Codeforces Round #232 (Div. 2) B题改了下题目描述罢了,连数据都是直接从那里拖来的。做法上机时讲过了,不多说。我的代码里用的都是除法,所以只需要int,有些人的代码需要乘法操作,极端数据下会爆int,需要用long long。
#include<cstdio>using namespace std;int main(){ int n,l,r; while(~scanf("%d%d%d",&n,&l,&r)) puts(n/l>(n-1)/r?"Yes":"No");}
B. 婚礼车队
不说数据结构是因为实在太明显了,可不是因为用不到……这道题的停车场是个典型的栈。每次判断栈顶是否符合所需编号,如果符合则出栈,否则将下一个元素进栈,依此类推。如果所有元素都已判断过且栈空则符合要求。由于自己太懒了直接扔个STL的,领会一下思想就好。
#include<cstdio>#include<algorithm>#include<stack>using namespace std;int main(){ int n,tmp; stack<int> data,st; while(~scanf("%d",&n)) { for(int i=0; i<n; ++i) { scanf("%d",&tmp); data.push(tmp); } bool flag=true; for(int i=n; flag&&i>=1; --i) { if(!st.empty()&&st.top()==i) { st.pop(); continue; } while(!data.empty()) { st.push(data.top()); data.pop(); if(st.top()==i) break; } if(st.top()!=i) flag=false; else st.pop(); } puts(flag?"Yes":"No"); while(!data.empty()) data.pop(); while(!st.empty()) st.pop(); }}
C. TXT Editer
陈题,一开始就认为这道题很好,一直留到上机。一方面可以用双链表来做,简单的移动插入删除。另外还可以用栈来做,拿两个栈,栈口相对,相接处就是光标。光标向左移动就是左栈元素弹出进右栈,反之亦然;插入删除都是对左栈进行的操作。非常巧妙。膜拜下提出此做法的昂神Orz……
先是链表版的,用STL因为我懒= =
//using list#include<cstdio>#include<cstring>#include<list>using namespace std;const int MAXN=500005;list<char> data;list<char>::iterator it;char op[MAXN];int main(){ int t; scanf("%d",&t); while(t--) { scanf("%s",op); int l=strlen(op); it=data.end(); for(int i=0; i<l; ++i) switch(op[i]) { case 'L': if(it!=data.begin()) --it; break; case 'R': if(it!=data.end()) ++it; break; case 'B': if(it!=data.begin()) it=data.erase(--it); break; default: data.insert(it,op[i]); } for(it=data.begin(); it!=data.end(); ++it) putchar(*it); putchar('\n'); data.clear(); }}
然后是用栈做的。
//using stack#include<cstdio>#include<cstring>#include<stack>using namespace std;const int MAXN=500005;stack<char> p,q;char op[MAXN];int main(){ int t; scanf("%d",&t); while(t--) { scanf("%s",op); int l=strlen(op); for(int i=0; i<l; ++i) switch(op[i]) { case 'L': if(!p.empty()) { q.push(p.top()); p.pop(); } break; case 'R': if(!q.empty()) { p.push(q.top()); q.pop(); } break; case 'B': if(!p.empty()) p.pop(); break; default: p.push(op[i]); } while(!p.empty()) { q.push(p.top()); p.pop(); } while(!q.empty()) { putchar(q.top()); q.pop(); } putchar('\n'); }}
我们注意到用栈做时,最后输出时为保证正序,需要将左栈元素全部弹入右栈,相当于光标移到最左侧,然后再从右栈中依次弹出并输出。太麻烦了,所以把左栈改成双端队列,嗯对还是STL。
//using deque+stack#include<cstdio>#include<cstring>#include<deque>#include<stack>using namespace std;const int MAXN=500005;deque<char> p;stack<char> q;char op[MAXN];int main(){ int t; scanf("%d",&t); while(t--) { scanf("%s",op); int l=strlen(op); for(int i=0; i<l; ++i) switch(op[i]) { case 'L': if(!p.empty()) { q.push(p.back()); p.pop_back(); } break; case 'R': if(!q.empty()) { p.push_back(q.top()); q.pop(); } break; case 'B': if(!p.empty()) p.pop_back(); break; default: p.push_back(op[i]); } while(!p.empty()) { putchar(p.front()); p.pop_front(); } while(!q.empty()) { putchar(q.top()); q.pop(); } putchar('\n'); }}
D. 表达式计算
陈题,书上有几乎所有的代码。我们严重怀疑当年的出题人在出数据的时候,代码里使用的是书上的float,所以这道题把float改成double的会WA……嗯对数据里有精度问题,我们一开始也没想到,说声sorry。其他的不多讲了。
#include<cstdio>using namespace std;const struct{ char ch; int pri;} lpri[7]= {{'=',0},{'(',1},{'*',5},{'/',5},{'+',3},{'-',3},{')',6}}, rpri[7]= {{'=',0},{'(',6},{'*',4},{'/',4},{'+',2},{'-',2},{')',1}};int leftpri(char op){ for(int i=0; i<7; i++) if(lpri[i].ch==op) return lpri[i].pri;}int rightpri(char op){ for(int i=0; i<7; i++) if(rpri[i].ch==op) return rpri[i].pri;}bool InOp(char ch){ return ch=='('||ch==')'||ch=='+'||ch=='-'||ch=='*'||ch=='/';}int Precede(char op1,char op2){ if(leftpri(op1)==rightpri(op2)) return 0; if(leftpri(op1)<rightpri(op2)) return -1; return 1;}void trans(char *exp,char postexp[]){ struct { char data[100]; int top; } op; int i=0; op.top=0; op.data[op.top]='='; while(*exp!='\0') { if(!InOp(*exp)) { while(*exp>='0'&&*exp<='9') postexp[i++]=*(exp++); postexp[i++]='#'; } else switch(Precede(op.data[op.top],*exp)) { case -1: op.data[++op.top]=*(exp++); break; case 0: --op.top; ++exp; break; case 1: postexp[i++]=op.data[op.top--]; break; } } while(op.data[op.top]!='=') postexp[i++]=op.data[op.top--]; postexp[i]='\0';}int compvalue(char *postexp){ struct { float data[100]; int top; } st; float d,a,b,c; st.top=-1; while(*postexp!='\0') { switch(*postexp) { case '+': a=st.data[st.top--]; b=st.data[st.top--]; c=a+b; st.data[++st.top]=c; break; case '-': a=st.data[st.top--]; b=st.data[st.top--]; c=b-a; st.data[++st.top]=c; break; case '*': a=st.data[st.top--]; b=st.data[st.top--]; c=a*b; st.data[++st.top]=c; break; case '/': a=st.data[st.top--]; b=st.data[st.top--]; c=b/a; st.data[++st.top]=c; break; default: d=0; while(*postexp>='0'&&*postexp<='9') d=d*10+*(postexp++)-'0'; st.data[++st.top]=d; break; } ++postexp; } return st.data[st.top];}int main(){ int t; scanf("%d",&t); while(t--) { char exp[100],postexp[100]; scanf("%s",exp); trans(exp,postexp); printf("%s\n%d\n",postexp,compvalue(postexp)); }}
E. Arthur爱打羽毛球
裸得不能再裸的队列。只要注意取出特定羽毛球的过程中,队头弹出编号,不是所要的,就再弹进队尾,直到找到特定编号或者转了一个圈就结束。
#include<cstdio>#include<queue>using namespace std;int main(){ int n,m,k; char op[10]; queue<int> q; while(~scanf("%d%d",&n,&m)) { while(m--) { scanf("%s",op); switch(op[0]) { case 'P': scanf("%d",&k); if(q.size()<n) puts("JUSTME"); else { q.pop(); puts("OOPS"); } q.push(k); break; case 'S': scanf("%d",&k); for(int i=0; i<q.size(); ++i) { if(q.front()==k) break; q.push(q.front()); q.pop(); } if(q.front()==k) { puts("GOTIT"); q.pop(); } else puts("WHERE"); break; case 'R': if(q.empty()) puts("NONE"); else { printf("%d\n",q.front()); q.pop(); } break; } } while(!q.empty()) q.pop(); }}
F. 括号匹配
书上例题的加强版。一种括号变成三种罢了,左括号进栈,右括号判断是否和栈顶匹配,很简单。放两个版本的标程。
#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;struct SqStack{ char data[105]; int top;};void InitStack(SqStack *&s){ s=(SqStack *)malloc(sizeof(SqStack)); s->top=-1;}void Push(SqStack *&s,char e){ s->data[++s->top]=e;}void Pop(SqStack *&s,char &e){ e=s->data[s->top--];}bool GetTop(SqStack *&s,char &e){ if(s->top==-1) return false; e=s->data[s->top]; return true;}int main(){ int t; scanf("%d",&t); while(t--) { char str[105],e; scanf("%s",str); bool match=true; SqStack *s; InitStack(s); int l=strlen(str); for(int i=0; match&&i<l; ++i) switch(str[i]) { case '(': case '[': case '{': Push(s,str[i]); break; case ')': case ']': case '}': if(GetTop(s,e)&&((e=='('&&str[i]==')')||(e=='['&&str[i]==']')||(e=='{'&&str[i]=='}'))) Pop(s,e); else match=false; break; } if(s->top!=-1) match=false; free(s); puts(match?"Yes":"No"); }}
#include<cstdio>#include<cstring>#include<stack>using namespace std;int main(){ int t; char str[100]; stack<char> s; scanf("%d",&t); while(t--) { scanf("%s",str); bool match=true; int l=strlen(str); for(int i=0; match&&i<l; ++i) switch(str[i]) { case '(': case '[': case '{': s.push(str[i]); break; case ')': case ']': case '}': if(!s.empty()&&((s.top()=='('&&str[i]==')')||(s.top()=='['&&str[i]==']')||(s.top()=='{'&&str[i]=='}'))) s.pop(); else match=false; break; } if(!s.empty()) match=false; puts(match?"Yes":"No"); while(!s.empty()) s.pop(); }}
G. 天马's wish
陈题,和F题无本质区别。注意Holmes虽然“通杀”但只是女性通杀,不是男女通杀……题干里已经说了他是男性Orz,给你们的想象力跪了……
#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<cctype>using namespace std;const int MAXN=100005;struct SqStack{ char data[MAXN]; int top;};void InitStack(SqStack *&s){ s=(SqStack *)malloc(sizeof(SqStack)); s->top=-1;}void Push(SqStack *&s,char e){ s->data[++s->top]=e;}void Pop(SqStack *&s,char &e){ e=s->data[s->top--];}bool GetTop(SqStack *&s,char &e){ if(s->top==-1) return false; e=s->data[s->top]; return true;}int main(){ char str[MAXN],e; while(~scanf("%s",str)) { int l=strlen(str)-2; SqStack *t; InitStack(t); for(int i=1; i<=l; i++) if(GetTop(t,e)) { if((str[i]!='%'&&e!='%')&&abs(e-str[i])=='a'-'A') Pop(t,e); else if(str[i]=='%'&&islower(e)) Pop(t,e); else if(e=='%'&&islower(str[i])) Pop(t,e); else Push(t,str[i]); } else Push(t,str[i]); puts(t->top==-1?"Yes":"No"); }}
#include<cstdio>#include<cstring>#include<cmath>#include<cctype>#include<stack>using namespace std;const int MAXN=100005;int main(){ char str[MAXN]; stack<char> s; while(~scanf("%s",str)) { int l=strlen(str)-2; for(int i=1; i<=l; i++) if(!s.empty()) { if((str[i]!='%'&&s.top()!='%')&&abs(s.top()-str[i])=='a'-'A') s.pop(); else if(str[i]=='%'&&islower(s.top())) s.pop(); else if(s.top()=='%'&&islower(str[i])) s.pop(); else s.push(str[i]); } else s.push(str[i]); puts(s.empty()?"Yes":"No"); while(!s.empty()) s.pop(); }}
说实话这次的题没啥激动人心的……大都是数据结构的基础操作,过3题以上才算比较理想(可能我想多了)……
- 第二次上机赛解题报告及标程
- 第一次上机赛解题报告及标程
- 第五次上机赛解题报告及标程
- 期末上机赛解题报告及标程
- 【作业解答】第二次上机作业解题报告
- 北京航空航天大学2014第二次上机解题报告
- 15级算法第二次上机解题报告
- 16级C++第二次上机解题报告
- 第二次上机指导报告
- 第二次C上机报告
- 第二次程序设计上机报告
- 第二次上机报告
- 第二次上机报告
- 第二次上机报告
- 第二次上机实验报告
- 第二次上机实验报告
- 第二次上机实验报告
- 第二次上机实验报告
- HTML5 地理定位 【来自百度应用分享平台】
- PHP平台的AFM-RPC实现----amfphp(二)HelloWorld范例
- HDU 1016 Prime Ring Problem
- java实现的统计随机数次数
- Android 进程生命周期 Process Lifecycle
- 第二次上机赛解题报告及标程
- 集合中线程安全
- Android内存管理、监测剖析
- 新浪微博的 【微博登陆按钮】部署在页面上后,登陆后,按钮始终未变
- #pragma GCC poison 的一个有趣特性
- 1. Struts2的工作机制
- 打包c#程序(续)
- poj 1753-Flip Game
- mysql-5.6.16-win32免安装配置方法