# HPU算法协会公开课第一期：【基础算法1】（STL 自定义sort 前缀和差分）

5 篇文章 0 订阅

STL简单入门

### A - 前m大的数

Input

Output

Sample Input
4 4
1 2 3 4
4 5
5 3 6 4
Sample Output
7 6 5 5
11 10 9 9 8

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
int a[3010],s[5000005];
bool cmp(int a,int b){
return a>b;
}
int main(){
int n,m;
while(cin>>n>>m){
int cnt=1;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
s[cnt++]=a[i]+a[j];
}
}
sort(s+1,s+cnt,cmp);
for(int i=1;i<m;i++) cout<<s[i]<<" ";
cout<<s[m]<<endl;
}
return 0;
}


### B - 稳定排序

Input

Output

Sample Input
3
aa 10
bb 10
cc 20
cc 20
bb 10
aa 10
3
aa 10
bb 10
cc 20
cc 20
aa 10
bb 10
3
aa 10
bb 10
cc 20
aa 10
bb 10
cc 20
Sample Output
Not Stable
cc 20
aa 10
bb 10
Right
Error
cc 20
aa 10
bb 10

（传送门（stable_sort()与sort()的用法区别）：https://blog.csdn.net/earbao/article/details/54911878）

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
struct student{
string id;
int score;
}a[310],b[310];
bool cmp(const student a, const student b){
return a.score>b.score;
}
int main(){
int n;
while(cin>>n){
for(int i=1;i<=n;i++) cin>>a[i].id>>a[i].score;
for(int i=1;i<=n;i++) cin>>b[i].id>>b[i].score;
stable_sort(a+1,a+n+1,cmp);//带有stable的函数可保证相等元素的原本相对次序在排序后保持不变
int cnt1=0,cnt2=0;
for(int i=1;i<=n;i++){
if(a[i].id==b[i].id) cnt1++;
if(a[i].score==b[i].score) cnt2++;
}
if(cnt1==n&&cnt2==n) cout<<"Right"<<endl;
else if(cnt1!=n&&cnt2==n){
cout<<"Not Stable"<<endl;
for(int i=1;i<=n;i++) cout<<a[i].id<<" "<<a[i].score<<endl;
}
else{
cout<<"Error"<<endl;
for(int i=1;i<=n;i++) cout<<a[i].id<<" "<<a[i].score<<endl;
}
}
return 0;
}


### C - 开门人和关门人

Input

Output

Sample Input
3
1
ME3021112225321 00:00:00 23:59:59
2
EE301218 08:05:35 20:56:35
MA301134 12:35:45 21:40:42
3
CS301111 15:30:28 17:00:10
SC3021234 08:00:00 11:25:25
CS301133 21:45:00 21:58:40
Sample Output
ME3021112225321 ME3021112225321
EE301218 MA301134
SC3021234 CS301133

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
map<string,string> mp1;
map<string,string> mp2;
int main(){
int t;
cin>>t;
while(t--){
mp1.clear();
mp2.clear();
int m;
cin>>m;
for(int i=1;i<=m;i++){
string id,in,out;
cin>>id>>in>>out;
mp1[in]=id;
mp2[out]=id;
}
map<string,string>::iterator it;
it=mp1.begin();
cout<<it->second<<" ";
it=mp2.end();it--;
cout<<it->second<<endl;
}
return 0;
}


### D - EXCEL排序

Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。
Input

Output

Sample Input
3 1
000007 James 85
000010 Amy 90
000001 Zoe 60
4 2
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 98
4 3
000007 James 85
000010 Amy 90
000001 Zoe 60
000002 James 90
0 0
Sample Output
Case 1:
000001 Zoe 60
000007 James 85
000010 Amy 90
Case 2:
000010 Amy 90
000002 James 98
000007 James 85
000001 Zoe 60
Case 3:
000001 Zoe 60
000007 James 85
000002 James 90
000010 Amy 90

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
struct student{
string id;
string name;
int score;
}stu[100010];
bool cmp1(const student a,const student b){
return a.id<b.id;
}
bool cmp2(const student a,const student b){
if(a.name==b.name) return a.id<b.id;
else return a.name<b.name;
}
bool cmp3(const student a,const student b){
if(a.score!=b.score) return a.score<b.score;
else return a.id<b.id;
}
int main(){
int n,c,k=1;
while(cin>>n>>c&&n){
for(int i=1;i<=n;i++) cin>>stu[i].id>>stu[i].name>>stu[i].score;
printf("Case %d:\n",k);k++;
if(c==1) sort(stu+1,stu+n+1,cmp1);
if(c==2) sort(stu+1,stu+n+1,cmp2);
if(c==3) sort(stu+1,stu+n+1,cmp3);
for(int i=1;i<=n;i++) cout<<stu[i].id<<" "<<stu[i].name<<" "<<stu[i].score<<endl;
}
return 0;
}


### H - 表达式括号匹配

2000

Sample Input
2+(3-4)-2-6)
Sample Output
NO

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
stack<char> c;
string s;
int main(){
cin>>s;
int l=s.size();
for(int i=0;i<l;i++){
if(s[i]=='(') c.push(s[i]);
if(s[i]==')'){
if(!c.empty()){
if(c.top()=='(') c.pop();
else c.push(s[i]);
}
else c.push(s[i]);
}
}
if(c.empty()) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}


### I - 合并果子

Input

Output

Sample Input
2
4
1 2 3 4
5
3 5 2 1 4
Sample Output
19
33

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7 + 5;
priority_queue< int,vector<int>,greater<int> > q;//优先队列
int main(){
int t;
cin>>t;
while(t--){
while(q.size()) q.pop();
int n;
cin>>n;
for(int i=0;i<n;i++){
int a;
cin>>a;
q.push(a);
}
ll res=0;
while(q.size()>=2){
int t1=q.top();
q.pop();
int t2=q.top();
q.pop();
res+=t1+t2;
q.push(t1+t2);
}
cout<<res<<endl;
}
return 0;
}


### J - Covered Points Count

You are given n segments on a coordinate line; each endpoint of every segment has integer coordinates. Some segments can degenerate to points. Segments can intersect with each other, be nested in each other or even coincide.

Your task is the following: for every k∈[1…n], calculate the number of points with integer coordinates such that the number of segments that cover these points equals k. A segment with endpoints li and ri covers point x if and only if li≤x≤ri.

Input
The first line of the input contains one integer n (1≤n≤2⋅105) — the number of segments.

The next n lines contain segments. The i-th line contains a pair of integers li,ri (0≤li≤ri≤1018) — the endpoints of the i-th segment.

Output
Print n space separated integers cnt1,cnt2,…,cntn, where cnti is equal to the number of points such that the number of segments that cover these points equals to i.

Examples
Input
3
0 3
1 3
3 8
Output
6 2 1
Input
3
1 3
2 4
5 7
Output
5 2 0
Note
The picture describing the first example:

Points with coordinates [0,4,5,6,7,8] are covered by one segment, points [1,2] are covered by two segments and point [3] is covered by three segments.

The picture describing the second example:

Points [1,4,5,6,7] are covered by one segment, points [2,3] are covered by two segments and there are no points covered by three segments.

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
map<ll,ll> mp;
ll cnt[maxn];
int main(){
ll n;
cin>>n;
for(ll i=1;i<=n;i++){
ll l,r;
cin>>l>>r;
mp[l]++;
mp[r+1]--;
}
ll last,ans=0;
map<ll,ll>::iterator it;
for(it=mp.begin();it!=mp.end();it++){
if(it==mp.begin()){
last=it->first;
ans+=it->second;
continue;
}
cnt[ans]+=it->first-last;
last=it->first;
ans+=it->second;
}
for(int i=1;i<=n;i++) cout<<cnt[i]<<(i==n ? "\n" : " ");
return 0;
}


### K - Ignatius and the Princess IV

“OK, you are not too bad, em… But you can never pass the next test.” feng5166 says.

“I will tell you an odd number N, and then N integers. There will be a special integer among them, you have to tell me which integer is the special one after I tell you all the integers.” feng5166 says.

“But what is the characteristic of the special integer?” Ignatius asks.

“The integer will appear at least (N+1)/2 times. If you can’t find the right integer, I will kill the Princess, and you will be my dinner, too. Hahahaha…” feng5166 says.

Can you find the special integer for Ignatius?
Input
The input contains several test cases. Each test case contains two lines. The first line consists of an odd integer N(1<=N<=999999) which indicate the number of the integers feng5166 will tell our hero. The second line contains the N integers. The input is terminated by the end of file.
Output
For each test case, you have to output only one line which contains the special number you have found.
Sample Input
5
1 3 2 3 3
11
1 1 1 1 1 5 5 5 5 5 5
7
1 1 1 1 1 1 1
Sample Output
3
5
1

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
map<int,int> mp;
int main(){
int n;
while(cin>>n){
mp.clear();
for(int i=1;i<=n;i++){
int x;cin>>x;
mp[x]++;
}
map<int,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++){
int x=it->second;
if(x>=((n+1)/2)){
x=it->first;
cout<<x<<endl;
break;
}
}
}
return 0;
}


### L - Stones

Because of the wrong status of the bicycle, Sempr begin to walk east to west every morning and walk back every evening. Walking may cause a little tired, so Sempr always play some games this time.
There are many stones on the road, when he meet a stone, he will throw it ahead as far as possible if it is the odd stone he meet, or leave it where it was if it is the even stone. Now give you some informations about the stones on the road, you are to tell me the distance from the start point to the farthest stone after Sempr walk by. Please pay attention that if two or more stones stay at the same position, you will meet the larger one(the one with the smallest Di, as described in the Input) first.
Input
In the first line, there is an Integer T(1<=T<=10), which means the test cases in the input file. Then followed by T test cases.
For each test case, I will give you an Integer N(0<N<=100,000) in the first line, which means the number of stones on the road. Then followed by N lines and there are two integers Pi(0<=Pi<=100,000) and Di(0<=Di<=1,000) in the line, which means the position of the i-th stone and how far Sempr can throw it.
Output
Just output one line for one test case, as described in the Description.
Sample Input
2
2
1 5
2 4
2
1 5
6 6
Sample Output
11
12

pair+优先队列的复杂使用，注意cmp的写法

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
typedef pair<int,int> pa;//pair用来存一对元素
struct cmp{//妙啊
bool operator()(pa a,pa b){
if(a.first==b.first) return a.second>b.second;//距离从小到大排序
else return a.first>b.first;//位置从小到大排序
}
};
priority_queue <pa,vector<pa>,cmp >q;
int main(){
int t;
cin>>t;
while(t--){
while(!q.empty()) q.pop();
int n;
cin>>n;
for(int i=1;i<=n;i++){
int p,d;
cin>>p>>d;
q.push(pa(p,d));
}
int cnt=1;
pa next;
while(!q.empty()){
next=q.top();
q.pop();
if(cnt&1) q.push(pa(next.first+next.second,next.second));
cnt++;
}
cout<<next.first<<'\n';
}
return 0;
}


### M - SnowWolf’s Wine Shop

After retired from hustacm, Sempr(Liangjing Wang) find a part-time-job in Snowwolf(Wei Xu)'s wine shop. There are different qualities of wine in the shop, and all of which has a rating describing the qualities. All the ratings are larger than 0 and smaller than 1,000,000. Everyday nearly Q people will go to his shop and buy a bottle of wine because of his kindness. Once a customer want an X qualified rating but there are no such one, Sempr will sell him a better one with the smallest rating. But the boss of the shop is Snowwolf, you know, so if no wine has no more than Y qualified ratings better than the customer’s request, Sempr will say sorry to them. Every morning, Xiangsanzi will send N bottles of different or same qualified wine.
Input
In the first line there is an Integer T(0<T<10), which means the number of test cases in the test file, then followed by T test cases.
For each test case;
In the first line, there are 3 Integers, N,Q and Y.
In the second line, there are N integers, which means the quality rating of each bottle of wines.
In the third line, there are Q integers, which means the requests of customers from dawn to dark.
Here, all the Integers are between 0 and 1,000,000
Output
For each test case, output “Case I:”, where I is the case number, then followed by Q different lines of integers, means the quality of wine Sempr will sell that time. If he could not sell any wine, just output -1.
Sample Input
2
2 3 3
2 3
1 2 3
2 3 0
2 3
3 1 2
Sample Output
Case 1:
2
3
-1
Case 2:
3
-1
2

multiset的使用（什么是multiset？就是一个不会去重但有序的集合）

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
multiset<int> wine;
int main(){
int t;
cin>>t;
for(int k=1;k<=t;k++){
wine.clear();
int n,q,y;
cin>>n>>q>>y;
for(int i=1;i<=n;i++){
int x;cin>>x;
wine.insert(x);
}
printf("Case %d:\n",k);
for(int i=1;i<=q;i++){
int x;cin>>x;
multiset<int>::iterator it=wine.lower_bound(x);//注意注意！！这个函数返回的是指针的位置
if(it==wine.end()||*it-x>y) cout<<-1<<endl;
else{
cout<<*it<<endl;
wine.erase(it);//把it所在位置的数删除
}
}
}
return 0;
}


### N - Alice, Bob and Candies

There are n candies in a row, they are numbered from left to right from 1 to n. The size of the i-th candy is ai.

Alice and Bob play an interesting and tasty game: they eat candy. Alice will eat candy from left to right, and Bob — from right to left. The game ends if all the candies are eaten.

The process consists of moves. During a move, the player eats one or more sweets from her/his side (Alice eats from the left, Bob — from the right).

Alice makes the first move. During the first move, she will eat 1 candy (its size is a1). Then, each successive move the players alternate — that is, Bob makes the second move, then Alice, then again Bob and so on.

On each move, a player counts the total size of candies eaten during the current move. Once this number becomes strictly greater than the total size of candies eaten by the other player on their previous move, the current player stops eating and the move ends. In other words, on a move, a player eats the smallest possible number of candies such that the sum of the sizes of candies eaten on this move is strictly greater than the sum of the sizes of candies that the other player ate on the previous move. If there are not enough candies to make a move this way, then the player eats up all the remaining candies and the game ends.

For example, if n=11 and a=[3,1,4,1,5,9,2,6,5,3,5], then:

move 1: Alice eats one candy of size 3 and the sequence of candies becomes [1,4,1,5,9,2,6,5,3,5].
move 2: Alice ate 3 on the previous move, which means Bob must eat 4 or more. Bob eats one candy of size 5 and the sequence of candies becomes [1,4,1,5,9,2,6,5,3].
move 3: Bob ate 5 on the previous move, which means Alice must eat 6 or more. Alice eats three candies with the total size of 1+4+1=6 and the sequence of candies becomes [5,9,2,6,5,3].
move 4: Alice ate 6 on the previous move, which means Bob must eat 7 or more. Bob eats two candies with the total size of 3+5=8 and the sequence of candies becomes [5,9,2,6].
move 5: Bob ate 8 on the previous move, which means Alice must eat 9 or more. Alice eats two candies with the total size of 5+9=14 and the sequence of candies becomes [2,6].
move 6 (the last): Alice ate 14 on the previous move, which means Bob must eat 15 or more. It is impossible, so Bob eats the two remaining candies and the game ends.
Print the number of moves in the game and two numbers:

a — the total size of all sweets eaten by Alice during the game;
b — the total size of all sweets eaten by Bob during the game.
Input
The first line contains an integer t (1≤t≤5000) — the number of test cases in the input. The following are descriptions of the t test cases.

Each test case consists of two lines. The first line contains an integer n (1≤n≤1000) — the number of candies. The second line contains a sequence of integers a1,a2,…,an (1≤ai≤1000) — the sizes of candies in the order they are arranged from left to right.

It is guaranteed that the sum of the values of n for all sets of input data in a test does not exceed 2⋅105.

Output
For each set of input data print three integers — the number of moves in the game and the required values a and b.

Example
Input
7
11
3 1 4 1 5 9 2 6 5 3 5
1
1000
3
1 1 1
13
1 2 3 4 5 6 7 8 9 10 11 12 13
2
2 1
6
1 1 1 1 1 1
7
1 1 1 1 1 1 1
Output
6 23 21
1 1000 0
2 1 2
6 45 46
2 2 1
3 4 2
4 4 3

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
int c[1010];
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>c[i];
int a=c[1],b=0,cnt1=1,cnt2=0,sum1=a,sum2=0;
for(int l=1,r=n+1;l<r;){
if(l+1==r) break;
b=0;
while(b<=a&&l<r-1){
r--;
b+=c[r];
}
sum2+=b;
cnt2++;
if(l+1==r) break;
a=0;
while(a<=b&&l<r-1){
l++;
a+=c[l];
}
sum1+=a;
cnt1++;
}
cout<<cnt1+cnt2<<" "<<sum1<<" "<<sum2<<endl;
}
return 0;
}


### O - Special Elements

Pay attention to the non-standard memory limit in this problem.

In order to cut off efficient solutions from inefficient ones in this problem, the time limit is rather strict. Prefer to use compiled statically typed languages (e.g. C++). If you use Python, then submit solutions on PyPy. Try to write an efficient solution.

The array a=[a1,a2,…,an] (1≤ai≤n) is given. Its element ai is called special if there exists a pair of indices l and r (1≤l<r≤n) such that ai=al+al+1+…+ar. In other words, an element is called special if it can be represented as the sum of two or more consecutive elements of an array (no matter if they are special or not).

Print the number of special elements of the given array a.

For example, if n=9 and a=[3,1,4,1,5,9,2,6,5], then the answer is 5:

a3=4 is a special element, since a3=4=a1+a2=3+1;
a5=5 is a special element, since a5=5=a2+a3=1+4;
a6=9 is a special element, since a6=9=a1+a2+a3+a4=3+1+4+1;
a8=6 is a special element, since a8=6=a2+a3+a4=1+4+1;
a9=5 is a special element, since a9=5=a2+a3=1+4.
Please note that some of the elements of the array a may be equal — if several elements are equal and special, then all of them should be counted in the answer.

Input
The first line contains an integer t (1≤t≤1000) — the number of test cases in the input. Then t test cases follow.

Each test case is given in two lines. The first line contains an integer n (1≤n≤8000) — the length of the array a. The second line contains integers a1,a2,…,an (1≤ai≤n).

It is guaranteed that the sum of the values of n for all test cases in the input does not exceed 8000.

Output
Print t numbers — the number of special elements for each of the given arrays.

Example
Input
5
9
3 1 4 1 5 9 2 6 5
3
1 1 2
5
1 1 1 1 1
8
8 7 6 5 4 3 2 1
1
1
Output
5
1
0
4
0

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
int a[8010],b[8010],vis[8010];
int main(){
int t;
cin>>t;
while(t--){
memset(vis,0,sizeof(vis));
int n,cnt=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i]+b[i-1];
}
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
int sum=b[j]-b[i-1];//前缀和求出所有子序列的和
if(sum<=n) vis[sum]++;
}
}
for(int i=1;i<=n;i++){
if(vis[a[i]]) cnt++;
}
cout<<cnt<<'\n';
}
return 0;
}


### P - Max Sum

Given a sequence a[1],a[2],a[3]…a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).
Output
For each test case, you should output two lines. The first line is “Case #:”, # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.
Sample Input
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
Sample Output
Case 1:
14 1 4

Case 2:
7 1 6

#include<bits/stdc++.h>
#define ull unsigned long long
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
int a[100008],dp[100008];
int main(){
int t;
cin>>t;
for(int k=1;k<=t;k++){
int n,m=-maxn,l=1,r=1,ml,mr,temp=1;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++){
if(a[i]>dp[i-1]+a[i]){
dp[i]=a[i];
l=i;r=i;
}
else{
dp[i]=dp[i-1]+a[i];
r=i;
}
if(dp[i]>m){
m=dp[i];
ml=l;
mr=r;
}
}
printf("Case %d:\n%d %d %d\n",k,m,ml,mr);
if(k!=t) cout<<endl;
}
return 0;
}

• 0
点赞
• 0
收藏
觉得还不错? 一键收藏
• 0
评论
02-02 241
08-24 855
08-09 200
05-28 1万+
01-20 193
11-22 1962
10-09 1万+
08-05 1162

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。