单选题
1-5 DDDCC
6-10 ADABC
编程题
7-1
本题主要考察C++ STL 中的list,也可使用其他容器
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
string s,name;
list<string> l;
cin>>n;
while(n--)
{
cin>>s;
if(s=="in")
{
cin>>name;
l.push_back(name);
}else if(s=="out")
{
l.pop_front();
}else if(s=="q")
{
if(l.empty())
{
cout<<"NULL"<<endl;
}else{
cout<<l.front()<<endl;
}
}
}
return 0;
}
7-2
本题主要考察C++ STL 中的map
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T,n;cin>>T;
map<string,int> v;
string temp;
while(T--)
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>temp;
v[temp]++;
}
for(auto it = v.begin();it!=v.end();it++)
{
auto pa = *it;
cout<<pa.first<<' '<<pa.second<<endl;
}
v.clear();
}
return 0;
}
7-3
本题主要考察C++ STL 中的stack
#include<iostream>
#include<stack>
#include<string>
using namespace std;
int main()
{
int T;
cin>>T;
string temp;
stack<char> s1;
int count = 0;
while(T--)
{
count = 0;
cin>>temp;
// cout<<temp.size()<<endl;
for( unsigned int i = 0; i <temp.size(); i++)
{
if(temp[i] == '{' || temp[i] == '[' || temp[i] == '(')
{
s1.push(temp[i]);
// cout<<i<<':'<<temp[i]<<endl;
continue;
// cout<<i<<endl;
}else
if(s1.empty())
{
count = 1;
break;
}
// cout<<i<<':'<<temp[i]<<endl;
if(temp[i] == '}')
{
if(s1.top()=='{') s1.pop();
else
{
count = 1;
break;
}
}else
if(temp[i] == ']')
{
if(s1.top()=='[') s1.pop();
else
{
count = 1;
break;
}
}else
if(temp[i] == ')')
{
if(s1.top() == '(' )s1.pop();
else
{
count = 1;
break;
}
}
}
if(!s1.empty())
{
count = 1;
// break;
}
if(count == 1) cout<<"No"<<endl;
if(count == 0)cout<<"Yes"<<endl;
while(!s1.empty())
{
s1.pop();
}
}
return 0;
}
7-4
本题考察队列,用a,b两个数组表示队列更方便
#include<bits/stdc++.h>
using namespace std;
int N[1010],a[1010],b[1010],d[1010];
int main(){
int n,j=0,k=0;//n:n为顾客,j:a队列的顾客数,k:b队列的顾客数
cin>>n;
for(int i=0;i<n;i++){
cin>>N[i];
if(N[i]%2!=0)
a[j++]=N[i];//奇数序号进入a队列
else
b[k++]=N[i];//偶数序号进入b队列
}
int l=0,p=0,m=0;//l:a队列中输出的顾客数,m:b队列中输出顾客数
for(int i=0;i<n;i++){
if(l<j){
d[m]=a[l];//把顾客的编号先输入到d队列中
m++;
l++;
d[m]=a[l];
m++;
l++;
}
if(p<k){
d[m]=b[p];
m++;
p++;
}
}
for(int i=0;i<m-1;i++){
cout<<d[i]<<' ';
}
cout<<d[m-1];//最后一个数不输出空格,可以输出‘!’测试下
return 0;
}
7-5
本题综合使用了queue,map,vector容器,综合性强,难度较大
#include<bits/stdc++.h>
using namespace std;
struct people
{
string name;
int arrive;
int cost;
};
queue<people> p[1001]; //下标为朋友圈编号
map<string,int> pyq,customerID; //key都为人名,pyq的值为朋友圈编号,customerID的值为到达顺序
vector<string> result; //存放结果顺序
int main()
{
int n,m;
cin>>n>>m;
int num=n;
int pyqNumber=1; //如果不是从1开始,在44行貌似会出错
while(m--)
{
int L;
cin>>L;
while(L--)
{
string tempPeople;
tempPeople.resize(20);
scanf("%s",&tempPeople[0]);
pyq[tempPeople.c_str()]=pyqNumber; //将人划分朋友圈
}
pyqNumber++;
}
people customer[num]; //创建一个结构体数组,按到达顺序存放每个人的数据
for(int i=0;i<n;i++)
{
string mz;
mz.resize(20);
scanf("%s %d %d",&mz[0],&customer[i].arrive,&customer[i].cost);
if(customer[i].cost>60)customer[i].cost=60;
customer[i].name=mz.c_str();
customerID[mz.c_str()]=i;
people temp; //临时变量,用于入队
temp.name=mz.c_str();
temp.arrive=customer[i].arrive;
temp.cost=customer[i].cost;
if(pyq.find(mz.c_str())==pyq.end()) //如果这个人没有朋友圈,他自己成一个圈
{
pyq[mz.c_str()]=pyqNumber;
pyqNumber++;
}
int Nopyq;
Nopyq=pyq[mz.c_str()]; //当前人的朋友圈编号
p[Nopyq].push(temp); //将这个人入队到所属朋友圈
}
int sum=0; //总等待时间
int now=customer[0].arrive; //能处理下一个人的时间
for(int i=0;i<num;i++) //按照输入顺序找
{
int pyqID=pyq[customer[i].name]; //当前人所属朋友圈编号
int j=0;
while(!p[pyqID].empty()) //从当前人的朋友圈的排队队列里找
{
int id=customerID[(p[pyqID].front()).name]; //当前朋友圈到达顺序最早的那个人
if(j>0&&customer[id].arrive>now) //如果朋友的到达时间大于下次处理的时间
break; //则帮不了朋友
if(now>customer[id].arrive)
{
sum+=now-customer[id].arrive;
now+=customer[id].cost;
}
else
now=customer[id].arrive+customer[id].cost;
result.push_back((p[pyqID].front()).name);
p[pyqID].pop();
j++;
}
}
for(int i = 0; i < result.size(); i++) { //输出结果
printf("%s\n", result[i].c_str());
}
printf("%.1f\n", sum*1.0/num);
return 0;
}
7-6
本题综合考察:线段树 + 贪心 + 区间修改
难度较大,23级的看不懂也没关系,22级可以尝试理解
#include "bits/stdc++.h"
#define ll long long
#define P pair<int, int>
using namespace std;
const int N = 1e7 + 10;
int tree[N];
int arr[N];
int lazy[N];
vector<P> v;
bool cmp(P a, P b){
if(a.second != b.second) {
return a.second < b.second;
}
return a.first < b.first;
}
void build(int root, int left, int right) {
if(left == right){
tree[root] = arr[left];
return;
}
int mid = (left + right) / 2;
int lchild = root * 2; // 咱们记根节点从1开始
int rchild = root * 2 + 1;
build(lchild, left, mid);
build(rchild, mid + 1, right);
tree[root] = min(tree[lchild], tree[rchild]);
}
void push_down(int root) { // 咱们就叫他向下传递
int lchild = root * 2;
int rchild = root * 2 + 1;
tree[lchild] += lazy[root]; // 赋值传递
tree[rchild] += lazy[root];
lazy[lchild] += lazy[root]; // 标记传递
lazy[rchild] += lazy[root];
lazy[root] = 0; // 完成任务, 标记取消
}
void update(int root, int left, int right, int need_l, int need_r, int val){
if(need_l <= left && right <= need_r){
lazy[root] += val;
tree[root] += val; // 咱们先不要管, 这个当然不对, 但是查询的时候的更新为正确值, 打上标记
return;
}
if(right < need_l || left > need_r){
return; // 当前区间不在更新范围, 直接退出
}
if(lazy[root] != 0) push_down(root); // 关键, 给标记过的值向下传递, 内容不更新的话值仍然为错误值
int mid = (left + right) / 2;
int lchild = root * 2;
int rchild = root * 2 + 1;
update(lchild, left, mid, need_l, need_r, val);
update(rchild, mid + 1, right, need_l, need_r, val);
tree[root] = min(tree[lchild], tree[rchild]);
}
ll query(int root, int left, int right, int need_l, int need_r){
if(need_l <= left && need_r >= right){
return tree[root];
}
if(need_l > right || need_r < left){
return LONG_LONG_MAX; // 最后一个样例大于INT_MAX,不能用0x3f3f3f3f
}
if(lazy[root] != 0) push_down(root);
int mid = (left + right) / 2;
int lchild = root * 2;
int rchild = root * 2 + 1;
ll l_come = query(lchild, left, mid, need_l, need_r);
ll r_come = query(rchild, mid + 1, right, need_l, need_r);
return min(l_come, r_come);
}
int main(){
int n, m;
cin>>n>>m;
for(int i = 1; i < n; i ++){
cin>>arr[i];
}
for(int i = 0; i < m; i++){
int x, y;
cin>>x>>y;
if(x > y) swap(x, y);
v.push_back({x, y});
}
build(1, 1, n - 1);
sort(v.begin(), v.end(), cmp);
ll res = 0;
for(int i = 0; i < v.size(); i++){
// v[i].first + 1, 仔细推推就出来了
ll val = query(1, 1, n - 1, v[i].first + 1, v[i].second);
res += val;
update(1, 1, n - 1, v[i].first + 1, v[i].second, -val);
}
cout<<res<<endl;
return 0;
}