7-1 银行业务队列简单模拟
分数 25
作者 DS课程组
单位 浙江大学
设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。
输入格式:
输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。
输出格式:
按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。
输入样例:
8 2 1 3 9 4 11 13 15输出样例:
1 3 2 9 11 4 13 15参考代码:
#include<bits/stdc++.h> using namespace std; int main(){ int n; cin>>n; vector<int> a,b; int num; for(int i=0;i<n;i++){ cin>>num; if(num%2==0){ b.push_back(num); }else a.push_back(num); } vector<int>re; while(!a.empty()||!b.empty()){ if(a.size()>=2){ re.push_back(a[0]); re.push_back(a[1]); a.erase(a.begin()); a.erase(a.begin()); }else if(!a.empty()){ re.push_back(a[0]); a.erase(a.begin()); } if(!b.empty()){ re.push_back(b[0]); b.erase(b.begin()); } } for(int i=0;i<re.size();i++){ cout<<re[i]; if(i!=re.size()-1) cout<<" "; } }7-2 表达式转换
分数 25
作者 DS课程组
单位 浙江大学
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、/以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4输出样例:
2 3 7 4 - * + 8 4 / +参考代码:
#include<stdio.h> #include<string.h> int main(){ char he[100]; int top=-1; int pr[100]; pr['+']=1;pr['-']=1; pr['*']=2;pr['/']=2; pr['(']=3;pr[')']=3; char str[20]; scanf("%s",str); int len=strlen(str); int flag=0; for(int i=0;i<len;i++){ if(((!i||str[i-1]=='(')&&(str[i]=='+'||str[i]=='-')) ||(str[i]>='0'&&str[i]<='9') ||str[i]=='.'){ if(flag) printf(" "); if(str[i]!='+') printf("%c",str[i]); while(str[i+1]=='.'||(str[i+1]>='0'&&str[i+1]<='9')){ i++; printf("%c",str[i]); } flag=1; }else{ if(str[i]==')'){ while(top!=-1&&he[top]!='('){ printf(" %c",he[top--]); } top--; }else if(top==-1||pr[str[i]]>pr[he[top]]){ he[++top]=str[i]; }else{ while(top!=-1&&he[top]!='('){ printf(" %c",he[top--]); } he[++top]=str[i]; } } } while(top!=-1){ printf(" %c",he[top--]); } return 0; }7-3 堆栈模拟队列
分数 25
作者 DS课程组
单位 浙江大学
设已知有两个堆栈S1和S2,请用这两个堆栈模拟出一个队列Q。
所谓用堆栈模拟队列,实际上就是通过调用堆栈的下列操作函数:
int IsFull(Stack S):判断堆栈S是否已满,返回1或0;int IsEmpty (Stack S ):判断堆栈S是否为空,返回1或0;void Push(Stack S, ElementType item ):将元素item压入堆栈S;ElementType Pop(Stack S ):删除并返回S的栈顶元素。
实现队列的操作,即入队void AddQ(ElementType item)和出队ElementType DeleteQ()。
输入格式:
输入首先给出两个正整数N1和N2,表示堆栈S1和S2的最大容量。随后给出一系列的队列操作:A item表示将item入列(这里假设item为整型数字);D表示出队操作;T表示输入结束。
输出格式:
对输入中的每个D操作,输出相应出队的数字,或者错误信息ERROR:Empty。如果入队操作无法执行,也需要输出ERROR:Full。每个输出占1行。
输入样例:
3 2 A 1 A 2 A 3 A 4 A 5 D A 6 D A 7 D A 8 D D D D T输出样例:
ERROR:Full 1 ERROR:Full 2 3 4 7 8 ERROR:Empty参考代码:
#include<bits/stdc++.h> using namespace std; stack <int>a,b; int main(){ int n,m; cin>>n>>m; if(n>m) swap(n,m); while(1){ char t; int k; cin>>t; if(t=='T') break; if(t=='A'){ cin>>k; if(a.size()<n){ a.push(k); }else if(b.empty()){ while(!a.empty()){ b.push(a.top()); a.pop(); } a.push(k); }else cout<<"ERROR:Full"<<endl; }else if(t=='D'){ if(!b.empty()){ cout<<b.top()<<endl; b.pop(); }else if(!a.empty()){ while(!a.empty()){ b.push(a.top()); a.pop(); } cout<<b.top()<<endl; b.pop(); }else cout<<"ERROR:Empty"<<endl; } } }7-4 输出全排列
分数 20
作者 DS课程组
单位 浙江大学
请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间。
输入格式:
输入给出正整数n(<10)。
输出格式:
输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1,a2,⋯,an排在序列b1,b2,⋯,bn之前,如果存在k使得a1=b1,⋯,ak=bk 并且 ak+1<bk+1。
输入样例:
3输出样例:
123 132 213 231 312 321参考代码:
#include<bits/stdc++.h> using namespace std; int main(){ int n; cin>>n; string str; for(int i=0;i<n;i++){ str+=i+1+'0'; } sort(str.begin(),str.end()); do{ cout<<str<<endl; }while(next_permutation(str.begin(),str.end())); }7-5 出栈序列的合法性
分数 25
作者 陈越
单位 浙江大学
给定一个最大容量为 m 的堆栈,将 n 个数字按 1, 2, 3, ..., n 的顺序入栈,允许按任何顺序出栈,则哪些数字序列是不可能得到的?例如给定 m=5、n=7,则我们有可能得到{ 1, 2, 3, 4, 5, 6, 7 },但不可能得到{ 3, 2, 1, 7, 5, 6, 4 }。
输入格式:
输入第一行给出 3 个不超过 1000 的正整数:m(堆栈最大容量)、n(入栈元素个数)、k(待检查的出栈序列个数)。最后 k 行,每行给出 n 个数字的出栈序列。所有同行数字以空格间隔。
输出格式:
对每一行出栈序列,如果其的确是有可能得到的合法序列,就在一行中输出YES,否则输出NO。
输入样例:
5 7 5 1 2 3 4 5 6 7 3 2 1 7 5 6 4 7 6 5 4 3 2 1 5 6 4 3 7 2 1 1 7 6 5 4 3 2输出样例:
YES NO NO YES NO参考代码:
#include<bits/stdc++.h> using namespace std; int main(){ int m,n,k; cin>>m>>n>>k; while(k--){ queue<int> q; stack<int> sta; int flag=0; for(int i=0;i<n;i++){ int num; cin>>num; q.push(num); } for(int i=1;i<=n;i++){ sta.push(i); while(!sta.empty()&&q.front()==sta.top()){ sta.pop(); q.pop(); } if(sta.size()>=m) flag=1; } if(!q.empty()){ flag=1; } if(flag) cout<<"NO"<<endl; else cout<<"YES"<<endl; } }7-6 括号匹配
分数 18
作者 周强
单位 青岛大学
检查一段C语言代码的小括号( )、 中括号[ ]和大括号{ }是否匹配。
输入格式:
在一行中输入一段C语言代码,长度不超过1000个字符(行末以换行符结束)。
输出格式:
第一行输出左括号的数量和右括号的数量,中间以一个空格间隔。
若括号是匹配的,在第二行打印YES,否则打印NO。
输入样例1:
for(int i=0; i<v; i++){ visited[i] = 0; for(int j=0; j<v; j++) scanf("%d",&(g->Adj[i][j])); }输出样例1:
8 8 YES输入样例2:
for(int i=0; i<v; i++) a(i]=0;输出样例2:
2 2 NO参考代码:
#include<stdio.h> #include<string.h> int main(){ char s[1001]; fgets(s,1001,stdin); int len=strlen(s); int lp=0,rp=0; int lb=0,rb=0; int lB=0,rB=0; for(int i=0;i<len;i++){ switch(s[i]){ case '(':lp++;break; case ')':rp++;break; case '[':lb++;break; case ']':rb++;break; case '{':lB++;break; case '}':rB++;break; default:break; } } int tl=lp+lb+lB; int tr=rp+rb+rB; printf("%d %d\n",tl,tr); char stack[1001]; int top=-1; int march=1; for(int i=0;i<len;i++){ char c=s[i]; if(c=='('||c=='['||c=='{'){ stack[++top]=c; }else if(c==')'||c==']'||c=='}'){ if(top==-1){ march=0; break; } char top_char=stack[top--]; if((c==')'&&top_char!='(')|| (c==']'&&top_char!='[')|| (c=='}'&&top_char!='{')){ march=0; break; } } } if(top!=-1){ march=0; } printf("%s\n",march?"YES":"NO"); }7-7 后缀式求值
分数 25
作者 周强
单位 青岛大学
我们人类习惯于书写“中缀式”,如3 + 5 * 2,其值为13。 (p.s. 为什么人类习惯中缀式呢?是因为中缀式比后缀式好用么?)
而计算机更加习惯“后缀式”(也叫“逆波兰式”,Reverse Polish Notation)。上述中缀式对应的后缀式是:3 5 2 * +
现在,请对输入的后缀式进行求值。
输入格式:
在一行中输入一个后缀式,运算数和运算符之间用空格分隔,运算数长度不超过6位,运算符仅有+ - * /四种。
输出格式:
在一行中输出后缀式的值,保留一位小数。
输入样例:
3 5.4 2.2 * +输出样例:
14.9参考代码:
#include <bits/stdc++.h> using namespace std; string s; double n1, n2; stack<double> stk; int main() { getline(cin, s); int n = s.size(); for(int i = 0; i < n; i ++) { if(s[i] == ' ') continue; else if ((s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') && (i == n - 1 || s[i + 1] == ' ')) { n1 = stk.top(); stk.pop(); n2 = stk.top(); stk.pop(); if(s[i] == '+') stk.push(n1 + n2); else if (s[i] == '-') stk.push(n2 - n1); else if (s[i] == '*') stk.push(n1 * n2); else stk.push(n2 / n1); } else { string t = ""; while(s[i] != ' ') { t += s[i]; i ++; } n1 = stof(t); stk.push(n1); } } printf("%.1f", stk.top()); }7-8 进制转换
分数 10
作者 sy
单位 宁波财经学院
输入十进制整数N和待转换的进制x(2、8、16),分别代表十进制N转换成二进制、八进制和十六进制,输出对应的结果。十六进制中A~F用大写字母表示。
输入格式:
输入两个整数N(十进制整数N)和x(x进制),中间用空格隔开。
输出格式:
输出对应的结果。
输入样例:
在这里给出一组输入。例如:
123 2输出样例:
在这里给出相应的输出。例如:
1111011输入样例:
在这里给出一组输入。例如:
123 16输出样例:
在这里给出相应的输出。例如:
7B参考代码:
#include<bits/stdc++.h> using namespace std; int main(){ int n,m; cin>>n>>m; stack<int> sta; if(m==2){ while(n){ sta.push(n%2); n/=2; } while(!sta.empty()){ cout<<sta.top(); sta.pop(); } }else if(m==8) printf("%o",n); else printf("%X",n); }7-9 行编辑器
分数 10
作者 夏仁强
单位 贵州工程应用技术学院
一个简单的行编辑程序的功能是:接受用户从终端输入的程序或数据,并存入用户的数据区。
由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的。较好的做法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区。允许用户输入出差错,并在发现有误时可以及时更正。例如,当用户发现刚刚键入的一个字符是错的时,可补进一个退格符"#",以表示前一个字符无效;
如果发现当前键入的行内差错较多或难以补救,则可以键入一个退行符"@",以表示当前行中的字符均无效。
如果已经在行首继续输入'#'符号无效。
输入格式:
输入一个多行的字符序列。但行字符总数(包含退格符和退行符)不大于250。
输出格式:
按照上述说明得到的输出。
输入样例1:
在这里给出一组输入。例如:
whli##ilr#e(s#*s)输出样例1:
在这里给出相应的输出。例如:
while(*s)输入样例2:
在这里给出一组输入。例如:
outcha@putchar(*s=#++);输出样例2:
在这里给出相应的输出。例如:
putchar(*s++);参考代码:
#include<bits/stdc++.h> using namespace std; int main(){ string s; while(getline(cin,s)){ string ss; int k=0; for(int i=0;i<s.size();i++){ if(i==0&&s[i]=='#') continue; else if(s[i]=='#') k--; else if(s[i]=='@') k=0; else ss[k++]=s[i]; } for(int i=0;i<k;i++){ cout<<ss[i]; } cout<<endl; } }7-10 选数
分数 20
作者 lg
单位 成都锦城学院
已知n个整数x1,x2,x3...xi,以及1个整数k(k<n)。从 n 个整数中任选 k个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4个整数分别为3,7,12,19 时,可得全部的组合与它们的和为:
3+7+12=22,
3+7+19=29,
7+12+19=38,
3+12+19=34,
现在,要求你计算出和为素数共有多少种。
例如上例,只有一种的和为素数:3+7+19=29
输入格式:
第一行两个空格隔开的整数 n,k(1≤n≤20,k<n)
第二行n个整数,两数之间空格隔开(1≤xi≤1000000)
输出格式:
输出一个整数,表示种类数。
输入样例:
在这里给出一组输入。例如:
4 3 3 7 12 19输出样例:
在这里给出相应的输出。例如:
1参考代码:
#include <bits/stdc++.h> using namespace std; int a[M], b[M], c[N], p[N]; int n, m, d, ans; int prime(int n) { if(n == 0 || n == 1) return 0; for(int i = 2; i <= n / i; i ++) if(n % i == 0) return 0; return 1; } void dfs(int x, int y) { if(x == m) { if(c[d] == 0) { c[d] == 1; p[d] = prime(d); } if(p[d]) ans ++; return; } for(int i = y; i <= n; i ++) { if(b[i] == 0) { b[i] = 1; d += a[i]; dfs(x + 1, i + 1); b[i] = 0; d -= a[i]; } } } int main() { cin >> n >> m; for(int i = 1; i <= n; i ++) cin >> a[i]; sort(a + 1, a + n + 1); dfs(0, 1); cout << ans; }7-11 猴子选大王
分数 20
作者 黄正鹏
单位 贵州工程应用技术学院
由M只猴子围成一圈,从1到M进行编号,打算从中选出一个大王,经过协商,决定选出大王的规则:从第一个开始循环报数,数到K的猴子出圈,下一个猴子从1开始报数,如此循环下去,最后剩下的一只猴子选为猴王。
输入格式:
输入一行中给两个正整数m,k。
输出格式:
输出当选猴王的编号。
输入样例:
在这里给出一组输入。例如:
3 2输出样例:
在这里给出相应的输出。例如:
3参考代码:
#include<stdio.h> int main(){ int m,k; scanf("%d %d",&m,&k); int king=0; for(int i=2;i<=m;i++){ king=(king+k)%i; } printf("%d",king+1); }