codeforces 1500分题部分题解(1249c2 770a 1264a 1253c 114b)

C2. Good Numbers (hard version)

注意 3x 意思是 3^x
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
The only difference between easy and hard versions is 
the maximum value of n.

You are given a positive integer number n. You really love good numbers 
so you want to find the smallest good number greater than or equal to n.

The positive integer is called good if it can be represented as a sum of 
distinct powers of 3 (i.e. no duplicates of powers of 3 are allowed).

For example:

30 is a good number: 30=33+31,
1 is a good number: 1=30,
12 is a good number: 12=32+31,
but 2 is not a good number: you can't represent it as a sum of distinct 
powers of 3 (2=3^0+3^0),
19 is not a good number: 
you can't represent it as a sum of distinct powers of 3 (for example, 
the representations 19=3^2+3^2+3^0=3^2+3^1+3^1+3^1+3^0 are invalid),
20 is also not a good number: you can't represent it as a sum of distinct 
powers of 3 (for example, the representation 20=32+32+30+30 is invalid).
Note, that there exist other representations of 19 and 20 as sums of 
powers of 3 but none of them consists of distinct powers of 3.

For the given positive integer n find such smallest m (n≤m) that m is a good number.

You have to answer q independent queries.

Input
The first line of the input contains one integer q (1≤q≤500) — the number of queries. 
Then q queries follow.

The only line of the query contains one integer n (1≤n≤1018).

Output
For each query, print such smallest integer m (where n≤m) that m is a good number.

Example
input
8
1
2
6
13
14
3620
10000
1000000000000000000
output
1
3
9
13
27
6561
19683
1350851717672992089

题目大意:

给你一个数字,找到最小的大于等于n的 good number
good number:The positive integer is called good if it can be represented
as a sum of distinct powers of 3 既一个数可以由k个互不同的3的幂次组成
预处理 f[i] = 3^i ; 1 <= i <= 38.
预处理 s[i] = s[i-1] + f[i].
i 从 38 开始到 1 ,如果他前面的s[i]<n,sum+=f[i],n-=f[i],并把i记录下来。

代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+15;
typedef long long ll;
ll t,n,f[N],lf[N];
int main()
{
    ll op=1e18+100;
    //cout<<op<<endl;
    f[1]=1;
    int k=0;
    for(int i=2;f[k]<=op;i++)
    {
        f[i]=f[i-1]*3;
        k=i;
      //  cout<<k<<endl;
    }
    lf[1]=1;
    for(int i=1;i<=k;i++)
    {
        lf[i]=lf[i-1]+f[i];
    //    cout<<i<<" "<<lf[i]<<endl;
    }
  //  cout<<k<<endl;
//    for()
    cin>>t;
    while(t--)
    {
        ll s=0;
        cin>>n;
        for(int i=k;i>=1;i--)
        {
            //cout<<n<<lf[i-1]
            if(lf[i-1]<n)
            {
                s+=f[i];
                n-=f[i];
            }
        }
        cout<<s<<endl;
    }
    return 0;
}

A. New Password

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Innokentiy decides to change the password in the social net "Contact!", 
but he is too lazy to invent a new password by himself. That is why he 
needs your help.

Innokentiy decides that new password should satisfy the following 
conditions:

the length of the password must be equal to n,
the password should consist only of lowercase Latin letters,
the number of distinct symbols in the password must be equal to k,
any two consecutive symbols in the password must be distinct.

Your task is to help Innokentiy and to invent a new password which 
will satisfy all given conditions.

Input
The first line contains two positive integers n and k
 (2 ≤ n ≤ 100, 2 ≤ k ≤ min(n, 26)) — the length of the password and the 
 number of distinct symbols in it.

Pay attention that a desired new password always exists.

Output
Print any password which satisfies all conditions given by Innokentiy.

Examples
inputCopy
4 3
outputCopy
java
inputCopy
6 6
outputCopy
python
inputCopy
5 2
outputCopy
phphp
Note
In the first test there is one of the appropriate new passwords — java, 
because its length is equal to 4 and 
3 distinct lowercase letters a, j and v are used in it.

In the second test there is one of the appropriate new passwords — python, 
because its length is equal to 6 and it consists of 6 distinct lowercase letters.

In the third test there is one of the appropriate new passwords — phphp, 
because its length is equal to 5 and 2 distinct lowercase letters 
p and h are used in it.

Pay attention the condition that no two identical symbols are consecutive 
is correct for all appropriate passwords in tests.

题意:

给定两个数字 n,k; 让你输出一个长度为n的字符串。
里面包含k个不同的字符(都是小写英文字符),而且相邻的字符不可以相同

思路:

k个不同的字符分别为 a,b,c... char('a'+k-1);
for循环直接输出,( i 要对k 取余即可 )。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+15;
typedef long long ll;
ll t,n,k,f[N],lf[N];
int main()
{
    cin>>n>>k;
    for(int i=0;i<n;i++)
    {
        cout<<char('a'+(i%k));
    }
    cout<<endl;
    return 0;
}

A. Beautiful Regional Contest

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
So the Beautiful Regional Contest (BeRC) has come to an end! n students took part in the contest. The final standings are already known: the participant in the i-th place solved pi problems. Since the participants are primarily sorted by the number of solved problems, then p1≥p2≥⋯≥pn.

Help the jury distribute the gold, silver and bronze medals. Let their numbers be g, s and b, respectively. Here is a list of requirements from the rules, which all must be satisfied:

for each of the three types of medals, at least one medal must be awarded (that is, g>0, s>0 and b>0);
the number of gold medals must be strictly less than the number of silver and the number of bronze (that is, g<s and g<b, but there are no requirements between s and b);
each gold medalist must solve strictly more problems than any awarded with a silver medal;
each silver medalist must solve strictly more problems than any awarded a bronze medal;
each bronze medalist must solve strictly more problems than any participant not awarded a medal;
the total number of medalists g+s+b should not exceed half of all participants (for example, if n=21, then you can award a maximum of 10 participants, and if n=26, then you can award a maximum of 13 participants).
The jury wants to reward with medals the total maximal number participants (i.e. to maximize g+s+b) so that all of the items listed above are fulfilled. Help the jury find such a way to award medals.

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

The first line of a test case contains an integer n (1≤n≤4⋅105) — the number of BeRC participants. The second line of a test case contains integers p1,p2,…,pn (0≤pi≤106), where pi is equal to the number of problems solved by the i-th participant from the final standings. The values pi are sorted in non-increasing order, i.e. p1≥p2≥⋯≥pn.

The sum of n over all test cases in the input does not exceed 4⋅105.

Output
Print t lines, the j-th line should contain the answer to the j-th test case.

The answer consists of three non-negative integers g,s,b.

Print g=s=b=0 if there is no way to reward participants with medals so that all requirements from the statement are satisfied at the same time.
Otherwise, print three positive numbers g,s,b — the possible number of gold, silver and bronze medals, respectively. The sum of g+s+b should be the maximum possible. If there are several answers, print any of them.
Example
inputCopy
5
12
5 4 4 3 2 2 1 1 1 1 1 1
4
4 3 2 1
1
1000000
20
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
32
64 64 63 58 58 58 58 58 37 37 37 37 34 34 28 28 28 28 28 28 24 24 19 17 17 17 17 16 16 16 16 11
outputCopy
1 2 3
0 0 0
0 0 0
2 5 3
2 6 6
Note
In the first test case, it is possible to reward 1 gold, 2 silver and 3 bronze medals. In this case, the participant solved 5 tasks will be rewarded with the gold medal, participants solved 4 tasks will be rewarded with silver medals, participants solved 2 or 3 tasks will be rewarded with bronze medals. Participants solved exactly 1 task won't be rewarded. It's easy to see, that in this case, all conditions are satisfied and it is possible to reward participants in this way. It is impossible to give more than 6 medals because the number of medals should not exceed half of the number of participants. The answer 1, 3, 2 is also correct in this test case.

In the second and third test cases, it is impossible to reward medals, because at least one medal of each type should be given, but the number of medals should not exceed half of the number of participants.

题意:

n个人参加比赛,你要给他们发奖牌,规定金牌获得者人数严格小于银牌获得者人数和铜牌
获得者人数,三种奖牌获得者人数都要大于0.
而且金牌获得者解题数严格大于银牌获得者解题数,银牌也同样严格大于铜牌。
问你是否可以根据规则发奖牌,如果可以就输出金银铜的数量,否则就输出0 0 0

思路

首先贪心,要保证有解,就要保证金牌获得者尽量少,总奖牌获得者数量尽量多。
1 先排序.
2 从n/2开始往前找,找到第一个满足可以被发铜牌的人。保证总奖牌人数足够多.
3 从1开始往后找,找到第一个满足可以被发金牌的人。保证金牌获得者最少。
4 从二倍金牌获得者的人数+1的下标开始找,找到第一个可以被发银牌的人。
  因为要在银牌获得者满足的条件下尽可能是铜牌获得者也满足。
5 进行判断是否有解,并进行输出。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=4e5+15;
typedef long long ll;
ll t,n,k,f[N],lf[N];
int a[N];
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        int k1=0,k2=0,k3=0;
        for(int i=n/2;i>=1;i--)
        {
            if(a[i]>a[i+1])
            {
                k1=i;
                break;
            }
        }
        for(int i=1;i<=n/2;i++)
        {
            if(a[i]>a[i+1])
            {
                k2=i;
                break;
            }
        }
        for(int i=k2+k2+1;i<=k1;i++)
        {
            if(a[i]>a[i+1])
            {
                k3=i;
                break;
            }
        }
       // cout<<k2<<" "<<k1<<" "<<k3<<endl;
        if(k1==0||k2==0||k3==0||k3-k2<=k2||k1-k3<=k2)
        {
            cout<<"0 0 0"<<endl;
        }
        else
        {
            cout<<k2<<" "<<k3-k2<<" "<<k1-k3<<endl;
        }
    }
    return 0;
}

B. Yet Another Array Partitioning Task

time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
An array b is called to be a subarray of a if it forms a continuous 
subsequence of a, that is, if it is equal to al, al+1, …, ar for some l,r.

Suppose m is some known constant. For any array, having m or more elements,
let's define it's beauty as the sum of m largest elements of that array. 
For example:
For array x=[4,3,1,5,2] and m=3, the 3 largest elements of x are 5, 4 and 3, 
so the beauty of x is 5+4+3=12.
For array x=[10,10,10] and m=2, the beauty of x is 10+10=20.
You are given an array a1,a2,…,an, the value of the said constant m and an integer k. 
Your need to split the array a into exactly k subarrays such that:

Each element from a belongs to exactly one subarray.
Each subarray has at least m elements.
The sum of all beauties of k subarrays is maximum possible.
Input
The first line contains three integers n, m and k (2≤n≤2⋅105, 1≤m, 2≤k, m⋅k≤n) 
— the number of elements in a, the constant m in the definition of beauty 
and the number of subarrays to split to.

The second line contains n integers a1,a2,…,an (−109≤ai≤109).

Output
In the first line, print the maximum possible sum of the beauties of the 
subarrays in the optimal partition.

In the second line, print k−1 integers p1,p2,…,pk−1 (1≤p1<p2<…<pk−1<n) 
representing the partition of the array, in which:

All elements with indices from 1 to p1 belong to the first subarray.
All elements with indices from p1+1 to p2 belong to the second subarray.
….
All elements with indices from pk−1+1 to n belong to the last, k-th subarray.
If there are several optimal partitions, print any of them.

Examples
inputCopy
9 2 3
5 2 5 2 4 1 1 3 2
outputCopy
21
3 5 
inputCopy
6 1 4
4 1 3 2 2 3
outputCopy
12
1 3 5 
inputCopy
2 1 2
-1000000000 1000000000
outputCopy
0
1 
Note
In the first example, one of the optimal partitions is 
[5,2,5], [2,4], [1,1,3,2].
The beauty of the subarray [5,2,5] is 5+5=10.
The beauty of the subarray [2,4] is 2+4=6.
The beauty of the subarray [1,1,3,2] is 3+2=5.
The sum of their beauties is 10+6+5=21.
In the second example, one optimal partition is [4], [1,3], [2,2], [3].

大意:

给定三个数 n,m,k;
再给你n个数:a1 到 an;
你要把它分成k部分,每部分的权值它里面最大的m个数的和.
令sum等于每一部分的权值相加,你要保证sum最大,输出sum,和你是怎么分割的。

思路:

根据题意很容易想到只要在序列a中选取它的前(m*k)个最大的元素就好了。
用一个数组b=a;sort b;就可以知道序列a中前(m*k)个最大的元素了。
因为数据大小原因,用map存一下a中前(m*k)个最大的元素中每个元素的出现次数。
然后遍历a,碰到一个mp[a[i]]>0的元素,该部分有效元素个数--;
该部分有效元素个数为零时,便可开一个新部分,走到头&走完k个有效部分时便可结束。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+15;
typedef long long ll;
ll t,n,k,m,b[N],c[N],a[N];
map<ll,int>mp;
bool cmp(ll a,ll b)
{
    return a>b;
}
int main()
{
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        b[i]=a[i];
    }
    ll sum=0;
    sort(b+1,b+1+n,cmp);
    for(int i=1;i<=k*m;i++)
    {
        sum+=b[i];
        mp[b[i]]++;
    }
    //cout<<mp[5]<<" "<<mp[4]<<" "<<mp[3]<<" "<<mp[2]<<endl;
    int lk=m,lt=1,cnt=0;
    for(int i=1;i<=n;i++)
    {
        if(mp[a[i]]>0)
        {
            mp[a[i]]--;
            lk--;
        }
        if(lk==0)
        {
            lk=m;
            c[lt]=i;
            lt++;
            if(lt==k)
                break;
        }
    }
    cout<<sum<<endl;
    for(int i=1;i<lt;i++)
        cout<<c[i]<<" ";
    cout<<endl;
    return 0;
}

C. Sweets Eating

time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Tsumugi brought n delicious sweets to the Light Music Club. 
They are numbered from 1 to n, where the i-th sweet has a sugar 
concentration described by an integer ai.

Yui loves sweets, but she can eat at most m sweets each day for health reasons.

Days are 1-indexed (numbered 1,2,3,…). Eating the sweet i at the d-th day 
will cause a sugar penalty of (d⋅ai), as sweets become more sugary with 
time. A sweet can be eaten at most once.

The total sugar penalty will be the sum of the individual penalties of each 
sweet eaten.

Suppose that Yui chooses exactly k sweets, and eats them in any order 

she wants. What is the minimum total sugar penalty she can get?

Since Yui is an undecided girl, she wants you to answer this question 
for every value of k between 1 and n.
Input
The first line contains two integers n and m (1≤m≤n≤200 000).
The second line contains n integers a1,a2,…,an (1≤ai≤200 000).

Output
You have to output n integers x1,x2,…,xn on a single line, separed 
by spaces, where xk is the minimum total sugar penalty Yui can get 
if she eats exactly k sweets.

Examples
inputCopy
9 2
6 19 3 4 4 2 6 7 8
outputCopy
2 5 11 18 30 43 62 83 121
inputCopy
1 1
7
outputCopy
7
Note
Let's analyze the answer for k=5 in the first example. Here is one of 
the possible ways to eat 5 sweets that minimize total sugar penalty:

Day 1: sweets 1 and 4
Day 2: sweets 5 and 3
Day 3 : sweet 6
Total penalty is 1⋅a1+1⋅a4+2⋅a5+2⋅a3+3⋅a6=6+4+8+6+6=30. We can prove that 
it's the minimum total sugar penalty Yui can achieve 
if she eats 5 sweets, hence x5=30.

题意:

给定n,m;a1到an;
你有n颗糖,每颗糖的权值是ai;一天最多能吃m颗,你在第k天吃某颗糖获得的权值是k*a[i]。
定义f[i]为你要吃i颗糖所获得的最小权值,请你输出f[1]到f[n].

思路:

很容易想到要吃i颗糖的权值最小,要有两个条件
1 要选权值最小的前i颗糖。
2 在这i颗糖中要先吃权值比较大的。
这时候就先想到要对序列a从小到大排序。
然后再想一个简单点的问题,就是m=1时;
显而易见,此时,f[i]=f[i-1]*2+a[i];考虑维护前缀和s,式子等效f[i]=f[i-1]+s[i].
然后就可得出当m>1时也具有类似的性质。就是分块思想。
既把i%m所得值相同的元素归为同一部分,既最多分为m部分。
然后对于同一部分中的元素可以利用m=1时的性质来求解。
因为此时一次前行m步,则共需走n/m步。
复杂度(m)*(n/m)等于O(n).

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+15;
typedef long long ll;
ll t,n,k,m,f[N],s[N],a[N];
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++)
        s[i]=s[i-1]+a[i];
    for(int d=0;d<=m-1;d++)
    {
        f[d]=s[d];
        for(int i=1;i*m+d<=n;i++)
        {
            f[i*m+d]=f[i*m+d-m]+s[i*m+d];
        }
    }
    for(int i=1;i<=n;i++)
        cout<<f[i]<<" ";
    return 0;
}
发布了18 篇原创文章 · 获赞 7 · 访问量 985

猜你喜欢

转载自blog.csdn.net/qq_43559193/article/details/104694236
今日推荐