第一题 约瑟夫问题
题目描述
n 个人围成一圈,从第一个人开始报数,数到 m的人出列,再由下一个人重新从 1开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。
注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰 n − 1名小朋友,而该题是全部出圈。
输入格式
输入两个整数 n , m 。
输出格式
输出一行 n 个整数,按顺序输出每个出圈人的编号。
样例 #1
样例输入 #1
10 3
样例输出 #1
3 6 9 2 7 1 8 5 10 4
提示
1 ≤ m , n ≤ 100
解题思路
1)纯模拟也可以做这道题目,这里练习一下队列的使用。
2)先将所有的元素压进队列,按找题目要求不断循环队列输出。
参考代码
#include<bits/stdc++.h> using namespace std; queue<int> a; int main() { int n,m; cin>>n>>m; for(int i=1;i<=n;i++) a.push(i); int cnt=1; while(!a.empty()) { if(cnt==m) { cout<<a.front()<<" "; a.pop(); cnt=1; } else { cnt++; a.push(a.front()); a.pop(); } } return 0; }
第二题 后缀表达式
题目描述
所谓后缀表达式是指这样的一个表达式:式中不再引用括号,运算符号放在两个运算对象之后,所有计算按运算符号出现的顺序,严格地由左而右新进行(不用考虑运算符的优先级)。
如:3*(5-2)+7 对应的后缀表达式为:3.5.2.-*7.+@。在该式中,@ 为表达式的结束符号。. 为操作数的结束符号。
输入格式
输入一行一个字符串 s,表示后缀表达式。
输出格式
输出一个整数,表示表达式的值。
样例 #1
样例输入 #1
3.5.2.-*7.+@
样例输出 #1
16
提示
数据保证,1 ≤ ∣ s ∣ ≤ 50,答案和计算过程中的每一个值的绝对值不超过 。
解题思路
1)利用栈保存数字,在遇到运算符时取栈顶的两个元素进行运算后再放回栈顶即可。
参考代码
#include<bits/stdc++.h> using namespace std; int main() { string a; int sum,k; stack <int> stk; cin>>a; for(int i=0;a[i]!='@';i++) { if(a[i]=='.') { sum=0,k=1; for(int j=i-1;j>=0&&a[j]>='0'&&a[j]<='9';j--) sum=sum+(a[j]-48)*k,k*=10; stk.push(sum); continue; } else if(a[i]>='0'&&a[i]<='9') { continue; } else { sum=stk.top(); stk.pop(); if(a[i]=='+') sum=stk.top()+sum; if(a[i]=='-') sum=stk.top()-sum; if(a[i]=='*') sum=stk.top()*sum; if(a[i]=='/') sum=stk.top()/sum; stk.pop(); stk.push(sum); } } cout<<stk.top(); return 0; }
第三题 【深基15.例1】询问学号
题目描述
有 n ( n ≤ 2 × ) 名同学陆陆续续进入教室。我们知道每名同学的学号(在 1 到之间),按进教室的顺序给出。上课了,老师想知道第 i 个进入教室的同学的学号是什么(最先进入教室的同学 i = 1 ),询问次数不超过次。
输入格式
第一行 2个整数 n 和 m,表示学生个数和询问次数。
第二行 n个整数,表示按顺序进入教室的学号。
第三行 m个整数,表示询问第几个进入教室的同学。
输出格式
输出 m个整数表示答案,用换行隔开。
样例 #1
样例输入 #1
10 3 1 9 2 60 8 17 11 4 5 14 1 5 9
样例输出 #1
1 8 5
解题思路
1)输入数组,进行数组查询再输出。
参考代码
#include<bits/stdc++.h> using namespace std; int main() { int a[2000001]; int n,m,x; cin>>n>>m; for(int i=1;i<=n;++i) cin>>a[i]; for(int i=1;i<=m;++i) { cin>>x; cout<<a[x]<<endl; } return 0; }
第四题【深基15.例2】寄包柜
题目描述
超市里有 n ( 1 ≤ n ≤ ) 个寄包柜。每个寄包柜格子数量不一,第 i个寄包柜有 a i ( 1 ≤ a i ≤ ) 个格子,不过我们并不知道各个 a i 的值。对于每个寄包柜,格子编号从 1 开始,一直到 a i 。现在有 q ( 1 ≤ q ≤) 次操作:
1 i j k:在第 i 个柜子的第 j 个格子存入物品 k ( 0 ≤ k ≤ )。当 k = 0时说明清空该格子。
2 i j:查询第 i个柜子的第 j 个格子中的物品是什么,保证查询的柜子有存过东西。
已知超市里共计不会超过个寄包格子,a i 是确定然而未知的,但是保证一定不小于该柜子存物品请求的格子编号的最大值。当然也有可能某些寄包柜中一个格子都没有。
输入格式
第一行 2 个整数 n 和 q ,寄包柜个数和询问次数。
接下来 q 个整数,表示一次操作。
输出格式
对于查询操作时,输出答案,以换行隔开。
样例 #1
样例输入 #1
5 4 1 3 10000 118014 1 1 1 1 2 3 10000 2 1 1
样例输出 #1
118014 1
解题思路
1)利用hash实现动态查找。
参考代码
#include<bits/stdc++.h> using namespace std; unordered_map<int,unordered_map<int,int>> a; int main() { int n,p,i,j,k; cin>>n>>n; while(n--) { cin>>p>>i>>j; if(p==2) cout<<a[i][j]<<endl; else { cin>>k; a[i][j]=k; } } return 0; }