【刷题日记】简单的STL练习题
眼红的Medusa(洛谷P1571)
题目描述
虽然 Miss Medusa 到了北京,领了科技创新奖,但是她还是觉得不满意。原因是:他发现很多人都和她一样获了科技创新奖,特别是其中的某些人,还获得了另一个奖项——特殊贡献奖。而越多的人获得了两个奖项,Miss Medusa就会越眼红。于是她决定统计有哪些人获得了两个奖项,来知道自己有多眼红。
输入格式
第一行两个整数 \(n, m\),表示有 \(n\) 个人获得科技创新奖,\(m\) 个人获得特殊贡献奖。
第二行 \(n\) 个正整数,表示获得科技创新奖的人的编号。
第三行 \(m\) 个正整数,表示获得特殊贡献奖的人的编号。
输出格式
输出一行,为获得两个奖项的人的编号,按在科技创新奖获奖名单中的先后次序输出。
样例 #1
样例输入 #1
4 3
2 15 6 8
8 9 2
样例输出 #1
2 8
提示
对于 \(60\%\) 的数据,\(0 \leq n, m \leq 1000\),获得奖项的人的编号 \(\lt 2 \times 10^9\);
对于 \(100\%\) 的数据,\(0 \leq n, m \leq 10^5\),获得奖项的人的编号 \(\lt 2 \times 10^9\)。
输入数据保证第二行任意两个数不同,第三行任意两个数不同。
题解
为了实现去重功能,可以使用map或set。既然输出要按照科技创新奖的获奖名单来,那就为其创造一个队列,先进先出即可。
AC代码
#include <bits/stdc++.h>
using namespace std;
map<long long,bool>mp;
queue<long long>que;
long long scan,n,m;
int main(){
scanf("%lld %lld",&n,&m);
for(long long i = 0;i<n;i++){
scanf("%lld",&scan);
que.push(scan);
}
for(long long i = 0;i<m;i++){
scanf("%lld",&scan);
mp[scan] = 1;
}
while(!que.empty()){
if(mp[que.front()]) printf("%lld ",que.front());
que.pop();
}
return 0;
}
小王子单链表(蓝桥1110)
题目
题解
AC代码
#include <bits/stdc++.h>
using namespace std;
list<int>a{1,2,3,4,5,6,7,8,9,10};
int m,x,num;
int main(){
scanf("%d",&m);
while(m--){
scanf("%d",&x);
a.remove(x);
a.push_front(x);
for(auto i:a) printf("%d ",i);
printf("\n");
}
return 0;
}
整数删除(蓝桥3515)
题目
题解
用数组做只能通过20%,用双向链表只能通过30%,正确做法是结合双向链表与优先队列,同时处理数据。
30%通过代码
#include <bits/stdc++.h>
using namespace std;
list<int>a;
long long n,k,scan,num;
int main(){
scanf("%lld %lld",&n,&k);
for(long long i = 0;i<n;i++){
scanf("%lld",&scan);
a.push_back(scan);
}
while(k--){
auto min_it = min_element(a.begin(),a.end());
num = *min_it;
if(min_it != a.begin()){
min_it --;
*min_it += num;
min_it ++;
}
min_it ++;
if(min_it != a.end()){
*min_it += num;
}
min_it --;
a.erase(min_it);
}
for(auto it:a) printf("%lld ",it);
return 0;
}
AC代码
#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
long long v[N],L[N],R[N],n,k,t; //用L、R两个数组实现双向链表
void del(long long x) { //删除元素
R[L[x]] = R[x];
L[R[x]] = L[x];
v[L[x]] += v[x];
v[R[x]] += v[x];
return;
}
priority_queue<pair<long long, long long>, vector<pair<long long, long long>>, greater<pair<long long, long long>>>Q;
//小根堆优先队列
int main(){
scanf("%lld %lld",&n,&k);
//构造双向链表
R[0] = 1;
L[n+1] = n;
for(long long i = 1;i<=n;i++){
cin >> v[i];
L[i] = i - 1;
R[i] = i + 1;
Q.push({v[i], i});
}
//重复模拟操作
while(k--){
auto p = Q.top();
Q.pop();
if(p.first != v[p.second]){ //该队头已经被del,需要撤销操作
Q.push({v[p.second],p.second});
k++;
}
else del(p.second);
}
t = R[0]; //R[0]指向第一个数
while(t != n + 1){
printf("%lld ",v[t]);
t = R[t];
}
return 0;
}
约瑟夫问题(洛谷P1996)
题目描述
\(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 \le m, n \le 100\)
题解
直接用队列即可。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
long long n,m,now = 0;
queue<int>q;
int main(){
scanf("%lld %lld",&n,&m);
for(long long i = 0;i<n;i++) q.push(i+1);
while(!q.empty()){
if(now != m-1){
now++;
q.push(q.front());
}
else{
now = 0;
printf("%lld ",q.front());
}
q.pop();
}
return 0;
}
餐厅排队(蓝桥3745)
题目
题解
双端队列,直接模拟。
AC代码
#include <bits/stdc++.h>
using namespace std;
queue<int>que;
int command,x,q;
int main(){
scanf("%d",&q);
while(q--){
scanf("%d",&command);
switch(command){
case 1:
scanf("%d",&x);
que.push(x);
break;
case 2:
que.pop();
break;
case 3:
printf("%d %d\n",que.front(),que.back());
break;
}
}
return 0;
}
小桥的神秘礼物盒(蓝桥3746)
题目
题解
跟上一题不能说一模一样吧。。只能说完全相同。。
AC代码
#include <bits/stdc++.h>
using namespace std;
long long n,command,x;
queue<long long>q;
int main(){
scanf("%lld",&n);
while(n--){
scanf("%lld",&command);
switch(command){
case 1:
scanf("%lld",&x);
q.push(x);
break;
case 2:
if(q.empty())
printf("lan\n");
else
q.pop();
break;
case 3:
if(q.empty())
printf("qiao\n");
else
printf("%lld\n",q.front());
break;
case 4:
printf("%lld\n",q.size());
break;
}
}
return 0;
}
小蓝的神奇复印机(蓝桥3749)
题目
题解
为了保证被删除的目标是重要程度最大的,可以同步地用一个优先队列去维护数据。
AC代码
#include <bits/stdc++.h>
using namespace std;
long long n,x,scan,ans = 0;
queue<pair<long long,bool>>q;
priority_queue<long long>pq;
int main(){
scanf("%lld %lld",&n,&x);
for(long long i = 0;i<n;i++){
scanf("%lld",&scan);
q.push({scan,i==x});
pq.push(scan);
}
//模拟任务
while(1){
if(q.front().first == pq.top()){ //确定是最重要的打印任务
ans ++;
pq.pop();
if(q.front().second){
printf("%lld",ans);
break;
}
q.pop();
}
else{
auto s = q.front();
q.pop();
q.push(s);
}
}
return 0;
}

浙公网安备 33010602011771号