A. Nearest Interesting Number
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Polycarp knows that if the sum of the digits of a number is divisible by 3, then the number itself is divisible by 3. He assumes that the numbers, the sum of the digits of which is divisible by 4, are also somewhat interesting. Thus, he considers a positive integer n interesting if its sum of digits is divisible by 4.
Help Polycarp find the nearest larger or equal interesting number for the given number a. That is, find the interesting number n such that n≥a and n is minimal.
Input
The only line in the input contains an integer a (1≤a≤1000).
Output
Print the nearest greater or equal interesting number for the given number a. In other words, print the interesting number n such that n≥a and n is minimal.
Examples
inputCopy
432
outputCopy
435
inputCopy
99
outputCopy
103
inputCopy
237
outputCopy
237
inputCopy
42
outputCopy
44
题意:找到一个距离n最近并且不小于n的各个数位和%4==0的数
题解:数据范围很小,暴力即可
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int a;
cin>>a;
for(int i=a;;i++){
int j=i;
int s=0;
while(j){
s+=(j%10);
j/=10;
}
if(s%4==0){
printf("%d\n",i);
return 0;
}
}
return 0;
}
B. Equalize Prices
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
There are n products in the shop. The price of the i-th product is ai. The owner of the shop wants to equalize the prices of all products. However, he wants to change prices smoothly.
In fact, the owner of the shop can change the price of some product i in such a way that the difference between the old price of this product ai and the new price bi is at most k. In other words, the condition |ai−bi|≤k should be satisfied (|x| is the absolute value of x).
He can change the price for each product not more than once. Note that he can leave the old prices for some products. The new price bi of each product i should be positive (i.e. bi>0 should be satisfied for all i from 1 to n).
Your task is to find out the maximum possible equal price B of all productts with the restriction that for all products the condiion |ai−B|≤k should be satisfied (where ai is the old price of the product and B is the same new price of all products) or report that it is impossible to find such price B.
Note that the chosen price B should be integer.
You should answer q independent queries.
Input
The first line of the input contains one integer q (1≤q≤100) — the number of queries. Each query is presented by two lines.
The first line of the query contains two integers n and k (1≤n≤100,1≤k≤108) — the number of products and the value k. The second line of the query contains n integers a1,a2,…,an (1≤ai≤108), where ai is the price of the i-th product.
Output
Print q integers, where the i-th integer is the answer B on the i-th query.
If it is impossible to equalize prices of all given products with restriction that for all products the condition |ai−B|≤k should be satisfied (where ai is the old price of the product and B is the new equal price of all products), print -1. Otherwise print the maximum possible equal price of all products.
Example
inputCopy
4
5 1
1 1 2 3 1
4 2
6 4 8 5
2 2
1 6
3 5
5 2 5
outputCopy
2
6
-1
7
Note
In the first example query you can choose the price B=2. It is easy to see that the difference between each old price and each new price B=2 is no more than 1.
In the second example query you can choose the price B=6 and then all the differences between old and new price B=6 will be no more than 2.
In the third example query you cannot choose any suitable price B. For any value B at least one condition out of two will be violated: |1−B|≤2, |6−B|≤2.
In the fourth example query all values B between 1 and 7 are valid. But the maximum is 7, so it’s the answer.
题意:给一个序列,要求一个最大的数使所有数字到这个数字的差值<=b,如果不存在输出-1
题解:排序之后输出a[1]+b或者-1即可
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
int a[105];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int q;
scanf("%d",&q);
while(q--){
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+1+n);
int ans=a[1]+k;
if(ans+k<a[n])printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
C. Computer Game
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vova is playing a computer game. There are in total n turns in the game and Vova really wants to play all of them. The initial charge of his laptop battery (i.e. the charge before the start of the game) is k.
During each turn Vova can choose what to do:
If the current charge of his laptop battery is strictly greater than a, Vova can just play, and then the charge of his laptop battery will decrease by a;
if the current charge of his laptop battery is strictly greater than b (b<a), Vova can play and charge his laptop, and then the charge of his laptop battery will decrease by b;
if the current charge of his laptop battery is less than or equal to a and b at the same time then Vova cannot do anything and loses the game.
Regardless of Vova’s turns the charge of the laptop battery is always decreases.
Vova wants to complete the game (Vova can complete the game if after each of n turns the charge of the laptop battery is strictly greater than 0). Vova has to play exactly n turns. Among all possible ways to complete the game, Vova wants to choose the one where the number of turns when he just plays (first type turn) is the maximum possible. It is possible that Vova cannot complete the game at all.
Your task is to find out the maximum possible number of turns Vova can just play (make the first type turn) or report that Vova cannot complete the game.
You have to answer q independent queries.
Input
The first line of the input contains one integer q (1≤q≤105) — the number of queries. Each query is presented by a single line.
The only line of the query contains four integers k,n,a and b (1≤k,n≤109,1≤b<a≤109) — the initial charge of Vova’s laptop battery, the number of turns in the game and values a and b, correspondingly.
Output
For each query print one integer: -1 if Vova cannot complete the game or the maximum number of turns Vova can just play (make the first type turn) otherwise.
Example
inputCopy
6
15 5 3 2
15 5 4 3
15 5 2 1
15 5 5 1
16 7 5 2
20 5 7 3
outputCopy
4
-1
5
2
0
1
Note
In the first example query Vova can just play 4 turns and spend 12 units of charge and then one turn play and charge and spend 2 more units. So the remaining charge of the battery will be 1.
In the second example query Vova cannot complete the game because even if he will play and charge the battery during each turn then the charge of the laptop battery will be 0 after the last turn.
题意:给出一个游戏规则,求最多进行1操作的次数
题解:二分次数检查即可
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
int a[105];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int q;
scanf("%d",&q);
while(q--){
ll k,n,a,b;
scanf("%lld%lld%lld%lld",&k,&n,&a,&b);
ll L=0;
ll R=n;
ll ans=-1;
while(L<=R){
ll mid=(L+R)/2;
if(mid*a+(n-mid)*b<k){
ans=mid;
L=mid+1;
}
else{
R=mid-1;
}
}
printf("%lld\n",ans);
}
return 0;
}
D. Candy Box (easy version)
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
This problem is actually a subproblem of problem G from the same contest.
There are n candies in a candy box. The type of the i-th candy is ai (1≤ai≤n).
You have to prepare a gift using some of these candies with the following restriction: the numbers of candies of each type presented in a gift should be all distinct (i. e. for example, a gift having two candies of type 1 and two candies of type 2 is bad).
It is possible that multiple types of candies are completely absent from the gift. It is also possible that not all candies of some types will be taken to a gift.
Your task is to find out the maximum possible size of the single gift you can prepare using the candies you have.
You have to answer q independent queries.
If you are Python programmer, consider using PyPy instead of Python when you submit your code.
Input
The first line of the input contains one integer q (1≤q≤2⋅105) — the number of queries. Each query is represented by two lines.
The first line of each query contains one integer n (1≤n≤2⋅105) — the number of candies.
The second line of each query contains n integers a1,a2,…,an (1≤ai≤n), where ai is the type of the i-th candy in the box.
It is guaranteed that the sum of n over all queries does not exceed 2⋅105.
Output
For each query print one integer — the maximum possible size of the single gift you can compose using candies you got in this query with the restriction described in the problem statement.
Example
inputCopy
3
8
1 4 8 4 5 6 3 8
16
2 1 3 3 4 3 4 4 1 3 2 2 2 4 1 1
9
2 2 4 4 4 7 7 7 7
outputCopy
3
10
9
Note
In the first query, you can prepare a gift with two candies of type 8 and one candy of type 5, totalling to 3 candies.
Note that this is not the only possible solution — taking two candies of type 4 and one candy of type 6 is also valid.
题意:有n个物品,每个物品的种类为ai,要求取出的每种种类的个数都不一样,求最多取出的总个数
题解:排序之后直接贪心地从多往少取即可
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
ll in[200005];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int q;
scanf("%d",&q);
while(q--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)in[i]=0;
for(int i=1;i<=n;i++){int w;scanf("%d",&w);in[w]++;}
sort(in+1,in+1+n);
ll ans=in[n];
ll maxx=in[n];
for(int i=n-1;i>=1;i--){
// if(in[i]!=in[i-1])ans+=in[i];
ans+=max(min(in[i],maxx-1),0ll);
maxx=min(maxx,max(min(in[i],maxx-1),0ll));
}
printf("%lld\n",ans);
}
return 0;
}
E. Subsequences (easy version)
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
The only difference between the easy and the hard versions is constraints.
A subsequence is a string that can be derived from another string by deleting some or no symbols without changing the order of the remaining symbols. Characters to be deleted are not required to go successively, there can be any gaps between them. For example, for the string “abaca” the following strings are subsequences: “abaca”, “aba”, “aaa”, “a” and “” (empty string). But the following strings are not subsequences: “aabaca”, “cb” and “bcaa”.
You are given a string s consisting of n lowercase Latin letters.
In one move you can take any subsequence t of the given string and add it to the set S. The set S can’t contain duplicates. This move costs n−|t|, where |t| is the length of the added subsequence (i.e. the price equals to the number of the deleted characters).
Your task is to find out the minimum possible total cost to obtain a set S of size k or report that it is impossible to do so.
Input
The first line of the input contains two integers n and k (1≤n,k≤100) — the length of the string and the size of the set, correspondingly.
The second line of the input contains a string s consisting of n lowercase Latin letters.
Output
Print one integer — if it is impossible to obtain the set S of size k, print -1. Otherwise, print the minimum possible total cost to do it.
Examples
inputCopy
4 5
asdf
outputCopy
4
inputCopy
5 6
aaaaa
outputCopy
15
inputCopy
5 7
aaaaa
outputCopy
-1
inputCopy
10 100
ajihiushda
outputCopy
233
Note
In the first example we can generate S = { “asdf”, “asd”, “adf”, “asf”, “sdf” }. The cost of the first element in S is 0 and the cost of the others is 1. So the total cost of S is 4.
题意:给出一个字符串,求k个不重复的子序列,要求子序列的总长度最长
题解:dp,dp[i][j]表示到达i处,长度为j的子序列的种类数,容易得出转移方程dp[i][j]=dp[i-1][j]+dp[i-1][j-1],而这样会在当前字符之前出现过的情况下重复计算一些子序列,所以要减去dp[k-1][j-1],其中k就是当前字符在之前出现的最后位置
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
ll last[27],dp[105][105];
char ch[105];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ll n,k;
scanf("%lld%lld",&n,&k);
scanf("%s",ch+1);
dp[0][0]=1;
for(int i=1;i<=n;i++){
int x=ch[i]-'a';
dp[i][0]=1;
for(int j=0;j<=i;j++){
dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
if(last[x])dp[i][j]-=dp[last[x]-1][j-1];
}
last[x]=i;
}
ll ans=0;
for(int i=n;i>=0;i--){
//debug(dp[n][i]);
if(k>dp[n][i]){
k-=dp[n][i];
ans+=dp[n][i]*(n-i);
}
else{
ans+=k*(n-i);
printf("%lld\n",ans);
return 0;
}
}
printf("-1\n");
return 0;
}
F. Topforces Strikes Back
time limit per test3 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
One important contest will take place on the most famous programming platform (Topforces) very soon!
The authors have a pool of n problems and should choose at most three of them into this contest. The prettiness of the i-th problem is ai. The authors have to compose the most pretty contest (in other words, the cumulative prettinesses of chosen problems should be maximum possible).
But there is one important thing in the contest preparation: because of some superstitions of authors, the prettinesses of problems cannot divide each other. In other words, if the prettinesses of chosen problems are x,y,z, then x should be divisible by neither y, nor z, y should be divisible by neither x, nor z and z should be divisible by neither x, nor y. If the prettinesses of chosen problems are x and y then neither x should be divisible by y nor y should be divisible by x. Any contest composed from one problem is considered good.
Your task is to find out the maximum possible total prettiness of the contest composed of at most three problems from the given pool.
You have to answer q independent queries.
If you are Python programmer, consider using PyPy instead of Python when you submit your code.
Input
The first line of the input contains one integer q (1≤q≤2⋅105) — the number of queries.
The first line of the query contains one integer n (1≤n≤2⋅105) — the number of problems.
The second line of the query contains n integers a1,a2,…,an (2≤ai≤2⋅105), where ai is the prettiness of the i-th problem.
It is guaranteed that the sum of n over all queries does not exceed 2⋅105.
Output
For each query print one integer — the maximum possible cumulative prettiness of the contest composed of at most three problems from the given pool of problems in the query.
Example
inputCopy
3
4
5 6 15 30
4
10 6 30 15
3
3 4 6
outputCopy
30
31
10
题意:给一个序列ai,取出3个数,要求这三个数不能出现ai%aj==0的情况,求三数之和的最大值
题解:排序之后暴力,加上部分判断剪枝
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
int a[200005];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int q;
scanf("%d",&q);
while(q--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){scanf("%d",&a[i]);}
sort(a+1,a+1+n);
int ans=a[n];
for(int i=n;i>=1;i--){
if(a[i]*3<=ans)break;
for(int j=i-1;j>=1;j--){
if(a[j]*2+a[i]<=ans)break;
if(a[i]%a[j]==0)continue;
for(int k=j-1;k>=1;k--){
if(a[k]+a[j]+a[i]<=ans)break;
if(a[j]%a[k]==0||a[i]%a[k]==0)continue;
ans=max(a[i]+a[j]+a[k],ans);
break;
}
ans=max(a[i]+a[j],ans);
while(j>=2&&a[j-1]==a[j])j--;
}
while(i>=2&&a[i-1]==a[i])i--;
}
printf("%d\n",ans);
}
return 0;
}
G. Candy Box (hard version)
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
This problem is a version of problem D from the same contest with some additional constraints and tasks.
There are n candies in a candy box. The type of the i-th candy is ai (1≤ai≤n).
You have to prepare a gift using some of these candies with the following restriction: the numbers of candies of each type presented in a gift should be all distinct (i. e. for example, a gift having two candies of type 1 and two candies of type 2 is bad).
It is possible that multiple types of candies are completely absent from the gift. It is also possible that not all candies of some types will be taken to a gift.
You really like some of the candies and don’t want to include them into the gift, but you want to eat them yourself instead. For each candy, a number fi is given, which is equal to 0 if you really want to keep i-th candy for yourself, or 1 if you don’t mind including it into your gift. It is possible that two candies of the same type have different values of fi.
You want your gift to be as large as possible, but you don’t want to include too many of the candies you want to eat into the gift. So, you want to calculate the maximum possible number of candies that can be included into a gift, and among all ways to choose maximum number of candies, you want to maximize the number of candies having fi=1 in your gift.
You have to answer q independent queries.
If you are Python programmer, consider using PyPy instead of Python when you submit your code.
Input
The first line of the input contains one integer q (1≤q≤2⋅105) — the number of queries.
The first line of each query contains one integer n (1≤n≤2⋅105) — the number of candies.
Then n lines follow, each containing two integers ai and fi (1≤ai≤n, 0≤fi≤1), where ai is the type of the i-th candy, and fi denotes whether you want to keep the i-th candy for yourself (0 if you want to keep it, 1 if you don’t mind giving it away).
It is guaranteed that the sum of n over all queries does not exceed 2⋅105.
Output
For each query print two integers:
the maximum number of candies in a gift you can compose, according to the constraints in the statement;
the maximum number of candies having fi=1 in a gift you can compose that contains the maximum possible number of candies.
Example
inputCopy
3
8
1 0
4 1
2 0
4 1
5 1
6 1
3 0
2 0
4
1 1
1 1
2 1
2 1
9
2 0
2 0
4 1
4 1
4 1
7 0
7 1
7 0
7 1
outputCopy
3 3
3 3
9 5
Note
In the first query, you can include two candies of type 4 and one candy of type 5. All of them have fi=1 and you don’t mind giving them away as part of the gift.
题意:给出n个物品的种类和01属性,要求取出的物品各个种类的个数不同,并且在取出总个数最大的前提下1属性尽可能多
题解:比D题多了一个01属性,所以就不能简单排序直接加了,因为不仅要取出个数最大还要1属性尽可能多。可以先按照每个种类的总个数(也就是0和1的数量)排序求出最大个数,然后按照属性个数(也就是1的数量)进行排序,然后二分1属性个数即可
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
int cnt[200005][2],ac[200005];
struct pot{
int aa;
int bb;
}p[200005];
int ans0,n;
bool cmp(struct pot aa,struct pot bb){
if(aa.aa!=bb.aa)return aa.aa>bb.aa;
return aa.bb>bb.bb;
}
bool cmp2(struct pot aa,struct pot bb){
//if(aa.aa!=bb.aa)return aa.aa>bb.aa;
return aa.bb>bb.bb;
}
bool check(int x){
int ac2=0;
int ac1=0;
set<int>st;
for(int i=1;i<=n;i++){
st.insert(i);
}
set<int>::iterator it;
for(int i=1;i<=n;i++){
/*if(x==3){
debug(i);
debug(p[i].aa);
debug(p[i].bb);
}*/
it=st.lower_bound(p[i].aa);
if(it==st.begin()&&(*it)>p[i].aa)continue;
if((*it)>p[i].aa)it--;
ac1+=(*it);
ac2+=min((*it),p[i].bb);
st.erase(it);
//if(x==3)debug(ac2);
}
//if(x==3){debug(ac1);debug(ac2);debug(ans0);debug(x);}
return ac2>=x&&ac1>=ans0;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int q;
scanf("%d",&q);
while(q--){
//int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)cnt[i][0]=cnt[i][1]=0;
for(int i=1;i<=n;i++){
int a,b;
scanf("%d%d",&a,&b);
cnt[a][b]++;
}
for(int i=1;i<=n;i++){
p[i].aa=cnt[i][0]+cnt[i][1];
p[i].bb=cnt[i][1];
}
sort(p+1,p+1+n,cmp);
ans0=p[1].aa;
int pre=p[1].aa;
for(int i=2;i<=n;i++){
ans0+=max(0,min(p[i].aa,pre-1));
pre=max(0,min(p[i].aa,pre-1));
}
sort(p+1,p+1+n,cmp2);
int L=0;
int R=n;
int ans1;
//debug(ans0);
while(L<=R){
int mid=(L+R)/2;
if(check(mid)){
ans1=mid;
L=mid+1;
}
else{
R=mid-1;
}
}
printf("%d %d\n",ans0,ans1);
}
return 0;
}
H. Subsequences (hard version)
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
The only difference between the easy and the hard versions is constraints.
A subsequence is a string that can be derived from another string by deleting some or no symbols without changing the order of the remaining symbols. Characters to be deleted are not required to go successively, there can be any gaps between them. For example, for the string “abaca” the following strings are subsequences: “abaca”, “aba”, “aaa”, “a” and “” (empty string). But the following strings are not subsequences: “aabaca”, “cb” and “bcaa”.
You are given a string s consisting of n lowercase Latin letters.
In one move you can take any subsequence t of the given string and add it to the set S. The set S can’t contain duplicates. This move costs n−|t|, where |t| is the length of the added subsequence (i.e. the price equals to the number of the deleted characters).
Your task is to find out the minimum possible total cost to obtain a set S of size k or report that it is impossible to do so.
Input
The first line of the input contains two integers n and k (1≤n≤100,1≤k≤1012) — the length of the string and the size of the set, correspondingly.
The second line of the input contains a string s consisting of n lowercase Latin letters.
Output
Print one integer — if it is impossible to obtain the set S of size k, print -1. Otherwise, print the minimum possible total cost to do it.
Examples
inputCopy
4 5
asdf
outputCopy
4
inputCopy
5 6
aaaaa
outputCopy
15
inputCopy
5 7
aaaaa
outputCopy
-1
inputCopy
10 100
ajihiushda
outputCopy
233
Note
In the first example we can generate S = { “asdf”, “asd”, “adf”, “asf”, “sdf” }. The cost of the first element in S is 0 and the cost of the others is 1. So the total cost of S is 4.
题意:给出一个字符串,求k个不重复的子序列,要求子序列的总长度最长
题解:dp,dp[i][j]表示到达i处,长度为j的子序列的种类数,容易得出转移方程dp[i][j]=dp[i-1][j]+dp[i-1][j-1],而这样会在当前字符之前出现过的情况下重复计算一些子序列,所以要减去dp[k-1][j-1],其中k就是当前字符在之前出现的最后位置
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cout<<#x<<" is "<<x<<endl;
typedef long long ll;
ll last[27],dp[105][105];
char ch[105];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
ll n,k;
scanf("%lld%lld",&n,&k);
scanf("%s",ch+1);
dp[0][0]=1;
for(int i=1;i<=n;i++){
int x=ch[i]-'a';
dp[i][0]=1;
for(int j=0;j<=i;j++){
dp[i][j]=dp[i-1][j]+dp[i-1][j-1];
if(last[x])dp[i][j]-=dp[last[x]-1][j-1];
}
last[x]=i;
}
ll ans=0;
for(int i=n;i>=0;i--){
//debug(dp[n][i]);
if(k>dp[n][i]){
k-=dp[n][i];
ans+=dp[n][i]*(n-i);
}
else{
ans+=k*(n-i);
printf("%lld\n",ans);
return 0;
}
}
printf("-1\n");
return 0;
}