目录
A - The Balance of the World
题意:
给出一个字符串,判断字符串中出现的括号是否全部匹配成功。
思路:
栈的入门题,简单的模拟就好了。
-
考察点:栈(Stack),数据结构,模拟
-
坑点:整行输入,输入结束条件
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
int main()
{
char c;
stack<char> s;
string ss;
while(1)
{
getline(cin,ss);
if(ss==".") break;
while(!s.empty()) s.pop();
for(int i=0; i<ss.size(); i++)
{
c=ss[i];
if(c=='('||c=='[')
s.push(c);
else if(c==')')
{
if(s.empty()||s.top()!='(')
s.push(c);
if(s.top()=='(')
s.pop();
}
else if(c==']')
{
if(s.empty()||s.top()!='[')
s.push(c);
if(s.top()=='[')
s.pop();
}
}
if(s.empty())
cout<<"yes"<<endl;
else
cout<<"no"<<endl;
}
}
B - Stones
题意:
最近小S的自行车坏了,他只能步行去学校了。
小S在去往学校的路上发现了很多小石头,正好他比较无聊,于是他便开始扔石头。
对小S的上学之路进行二维化形成坐标系(二向箔警告),小S初始位置为0。
在坐标轴的一些位置上散落着石头,每个石头能够被扔出去的距离为di。
当小S遇到一个石头时,他会先去数这是他碰到的第几个石头:
- 如果是第偶数个石头,小S会觉得它很无聊,会忽略它继续走;
- 如果是第奇数个石头,小S会把它向前扔di米。
如果有多个石头落在了同一个坐标下,小S会依据它们的di由小到大的去处理这些石头。
小S想知道他最远会在哪里停下来(当没有石头可以扔的时候小S会停下思考人生)。
思路:
定义结构体node存储每块石头的信息:
struct node
{
int pos,x;
bool operator<(const node a)const{ //重载运算符,定义优先级
if(a.pos!=pos) return a.pos<pos;
else return a.x<x;
}
}zh;
将每块石头都存到优先队列中,优先级为距离由小到大,次优先级为被扔距离由小到大。
接下来模拟就好了。
-
考察点:优先队列(Priority queue),数据结构,模拟,运算符重载
代码:
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<stdio.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
struct node
{
int pos,x;
bool operator<(const node a)const{ //重载运算符,定义优先级
if(a.pos!=pos) return a.pos<pos;
else return a.x<x;
}
}zh;
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
priority_queue<node> p;
for(int i=0;i<n;i++){
cin>>zh.pos>>zh.x;
p.push(zh);
}
int pos=0;
int num=0;
while(!p.empty()){
node tmp=p.top();
p.pop();
num++;
//cout<<tmp.pos<<" "<<tmp.x<<endl;
if(num&1){
tmp.pos+=tmp.x;
p.push(tmp);
}
else{
pos=tmp.pos;
}
}
cout<<pos<<endl;
}
}
C - Running Median
题意:
给定一个长为n的序列,请你求出每当我们考虑前k(k=1;k<=n;k+=2)个数字时中位数是多少?
思路:
本套题最好玩的题(精华所在)。
对于奇数长度的序列,小于中位数的数的数量num1与大于中位数的数的数量num2满足:
num1==num2==n/2
我们可以利用这个性质,设计两个优先队列形成对顶堆:
priority_queue<int> p1; //大根堆,存储小于等于中位数的数,p1.top()为中位数
priority_queue<int,vector<int>,greater<int> > p2; //小根堆,存储大于中位数的数
接下来模拟题目过程,维护num1( p1.top()-1 )与num2( p2.top() )的关系。
-
考察点: 优先队列(Priority queue),数据结构,模拟,对顶堆
-
难点:设计对顶堆,找出p1、p2之间的关系
-
坑点:阴间的输出格式
代码:
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<stdio.h>
using namespace std;
typedef long long ll;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int x,n,a;
scanf("%d%d",&x,&n);
priority_queue<int> p1;
priority_queue<int,vector<int>,greater<int> > p2;
vector<int> ans;
for(int i=1; i<=n; i++)
{
scanf("%d",&a);
if(p1.empty())
p1.push(a);
else
{
if(a>p1.top())
p2.push(a);
else
p1.push(a);
}
while(p1.size()<p2.size())
{
p1.push(p2.top());
p2.pop();
}
while(p2.size()<p1.size()-1)
{
p2.push(p1.top());
p1.pop();
}
if(i&1)
ans.push_back(p1.top());
}
printf("%d %d\n",x,ans.size());
for(int i=1; i<=ans.size(); i++)
{
if(i%10!=1)
printf(" ");
printf("%d",ans[i-1]);
if(i%10==0)
printf("\n");
}
printf("\n");
}
}
D - Let the Balloon Rise
题意:
给出n个字符串,输出出现次数最多的字符串。
思路:
map的模板题,套就完了。
-
考察点:映射对(Map),数据结构
代码:
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<stdio.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
int main()
{
int n;
while(cin>>n&&n)
{
string ss;
map<string,int> mp;
for(int i=0;i<n;i++){
cin>>ss;
mp[ss]++;
}
map<string,int>::iterator it;
int maxx=-1;
string answer;
for(it=mp.begin();it!=mp.end();it++){
if(it->second > maxx){
answer=it->first;
maxx=it->second;
}
}
cout<<answer<<endl;
}
}
E - Shopping
题意:
现在一共有n家商店正在竞选风都第一店的名号,由你所经营的一家叫做“memory”的商店也在竞选名单之中。
每一天都会有人为这n家商店进行投票。
你想知道在每天的投票结束后你的商店可以排到第几。
(主场优势:如果另一家店的票数和“memory”的票数一样,我们则认为“memory”更加占据优势。 什么?你问我为什么? 主办方规定的,他们还负责今年的东京奥运会)
思路:
map的模板题2,每次找票数多于memory的店家数量。
-
考察点:映射对(Map),数据结构
代码:
#include<bits/stdc++.h>
#define inf 0x3f3f3f
using namespace std;
const int maxn=1e5+10;
typedef long long ll;
string shop="memory";
int main()
{
int n,day,x;
string s;
while(cin>>n)
{
map<string,int>q;
for(int i=0; i<n; i++)
{
getchar();
cin>>s;
q[s]=0;
}
cin>>day;
for(int i=0; i<day; i++)
{
for(int j=0; j<n; j++)
{
getchar();
cin>>x>>s;
q[s]+=x;
// cout<<s<<":"<<q[s]<<endl;
}
map<string,int>::iterator it;
int ans=1;
for(it=q.begin(); it!=q.end(); it++)
if(q[shop]<it->second)
ans++;
cout<<ans<<endl;
}
}
}
F - pairs
题意:
给定长度为n的序列x,请问你能找到多少对(i,j)(i < j)满足 | x[i] - x[j] | <= k。
思路:
使用lower_bound二分查找x[i]+k的位置pos,如果x[pos]-x[i]==k,则有pos-i对;否则有pos-i-1对。
-
考察点:二分查找,数据结构,STL
代码:
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<stdio.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
ll a[maxn];
int main()
{
int t;
cin>>t;
while(t--)
{
ll n,k;
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
ll cnt=0;
for(int i=0;i<n;i++){
int posa=lower_bound(a,a+n,a[i]+k)-a;
if(posa==n) posa--;
cnt+=posa-i-1;
if(a[posa]-a[i]<=k) cnt++;
}
cout<<cnt<<endl;
}
}
G - 产生冠军
题意:
思路:
产生冠军的条件:
只有一个人没有输过。
没有输过:名字没有出现在右边。
使用set容器帮助我们处理过程。
-
考察点:集合(Set),数据结构,STL
代码:
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<stdio.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+100;
int main()
{
int n;
while(cin>>n&&n)
{
set<string> s;
set<string> ss;
string x,y;
for(int i=0; i<n; i++)
{
cin>>x>>y;
s.insert(y);
ss.insert(x);
}
int cnt=0;
set<string>::iterator it;
for(it=ss.begin(); it!=ss.end(); it++)
{
if(s.find(*it)!=s.end())
continue;
else
cnt++;
}
if(cnt==1)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
}
H - Kiki & Little Kiki 1
题意:
编写一个程序,模拟kiki所说的 “小kiki容器” 。
“小kiki容器”具有一下操作:
- Push M:将M加入容器;
- Pop M:从容器找寻找第一个小于等于M的数输出并从容器中删除,若不存在该数则输出“No Element!”
思路:
显而易见的模拟题。
multiset(可重复集合)是博主认为比较适合的容器。
模拟就完事了。
-
考察点:可重复集合(multiset),数据结构,STL,二分查找
-
坑点:multiset::erase()函数的参数究竟有哪些,什么含义
代码:
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<stdio.h>
using namespace std;
typedef long long ll;
multiset<int> mts;
multiset<int>::iterator it;
char ss[10];
int main()
{
int n;
while(~scanf("%d",&n)){
mts.clear();
int x;
while(n--){
scanf("%s%d",ss,&x);
if(ss[1]=='u')
mts.insert(x);
else{
it=mts.lower_bound(x);
if(*it==x){
printf("%d\n",x);
mts.erase(it);
}
else if(*it!=x){
if(it==mts.begin())
printf("No Element!\n");
else{
it--;
printf("%d\n",*it);
mts.erase(it);
}
}
}
}
printf("\n");
}
}