Codeforces Round #653 (Div. 3)部分题解

A - Required Remainder

题解:这个题应该是有很多种解法,这里提供一种比较暴力的方法,我们先把ans去取一个比较大的值,如果这个值大于n的话我们就让他减去一个x,因为减去一个x是对取模结果没有影响的,如果ans小于n的话,直接输出答案即可。

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 2e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;

int main()
{
    int t;
    cin>>t;
    while(t--){
        int x,y,n;
        cin>>x>>y>>n;
        int ans,times=n/x;
        while(true){
            ans=times*x+y;
            times--;
            if(ans<=n){
                cout<<ans<<endl;
                break;
            }
        }
    }
    return 0;
}


B - Multiply by 2, divide by 6

题意:这个题,对于一个n,你可以进行两种操作,一种是除以6(必须整除),一种是乘2。
题解:仔细分析一下,3*2=6,所以说,这个二的作用,就是把3变成6,这个步骤一合并,就相当于两步,第一步是把三变成6,第二部是把6变成1.
综上所述,一共有两个过程:
1.直接把6变成1.(耗费1步)
2.把3先变成6,再把6变成1(耗费两步)

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 2e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;

int main()
{
    int t;
    cin>>t;
    while(t--){
        int cnt1=0,cnt2=0;
        while(n%6==0) n/=6,cnt1++;
        while(n%3==0) n/=3,cnt2++;
        if(n==1) cout<<cnt1+cnt2*2<<endl;
        else cout<<-1<<endl;
    }
    return 0;
}


C - Move Brackets

题意:一共给你2n个阔号,一半是 ‘(’ ,一半是 ‘)’ 这些括号是乱序的,你可以把某个阔号往最头上或者是最后面放置,问问你最少几次可以把阔号匹配完成。
题解:这个题,你会发现,一个括号往开头放和往结尾放置他的代价是相同的,开阔号的话必然是往开头放,闭括号肯定是往结尾放,那么我么可以选择只动一个类型的阔号,比如说只动闭阔号,我们从头往后遍历,当开阔号数量小于闭阔号数量时,我们选择移动一个闭阔号往右端(同时减去一个闭阔号的数量)。不断记录即可

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 2e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;

string s;
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        cin>>s;
        int ans1=0,ans2=0;
        int sum=0;
        for(int i=0;i<n;i++){
            if(s[i]=='(') ans1++;
            else ans2++;
            if(ans2>ans1) sum++,ans2--;
        }
        cout<<sum<<endl;
    }
    return 0;
}


D - Zero Remainder Array

思路参考:https://blog.csdn.net/weixin_45483201/article/details/107014826?%3E
代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 2e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;

int a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--){
        int n,k;
        cin>>n>>k;
        for(int i=0;i<n;i++){
            int x;
            scanf("%d",&x);
            a[i]=x%k;
        }
        sort(a,a+n,greater<int>());
        int cnt=1,imax=1,ans=a[0];
        for(int i=1;i<n;i++){
            if(!a[i]) break;
            if(a[i]==a[i-1])  cnt++;
            else cnt=1;
            if(cnt>=imax) imax=cnt,ans=a[i];
        }
        if(ans==0) printf("0\n");
        else printf("%lld\n",1ll*k*(imax-1)+k-ans+1);
    }
    return 0;
}


E1 - Reading Books (easy version)

题意:一共有n本书,看完每本书都有一个花费时间,每本书上都有两个标记,小a是否喜换,小b是否喜换,小a小b是否共同喜换,他们只会阅读自己喜换的书,他们每个人至少阅读k本书,如果他俩共同喜换,那么花费阅读这一本书的时间,会使他俩已经阅读的书总是各加一,求花费最少时间阅读完成k本书的情况,如果无法完成则输出-1。
题解:
那么我们对每本书的情况进行分类
1.小a喜换小b不喜欢。
2.小b喜换小a不喜欢。
3.小a小b都喜欢。
4.小a小b都不喜欢。

这四种情况,可以看出第4种情况的书没有意义,我们直接丢弃即可(因为没人会去看)
那么我们先特判完不成的情况,如果min(第一种情况,第二种情况)+第三种情况,小于k,那么就说明没有那么多书可以让他们看,直接输出-1;
对于可以完成的情况,我们对a,b数组先排序,(a情况时间+b情况时间)=c情况时间。

所以我们可以把(a情况时间+b情况时间)(每次取最小a和b)丢尽优先队列,然后把c情况丢尽优先队列。
然后取有限队列前k个数相加即可

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 2e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
int a[maxn],b[maxn],c[maxn];
int main()
{
    int n,k;
    cin>>n>>k;
    int cnt1=0,cnt2=0,cnt3=0;
    for(int i=0;i<n;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        if(y==1&&z==0) a[cnt1++]=x;
        else if(y==0&&z==1) b[cnt2++]=x;
        else if(y==1&&z==1) c[cnt3++]=x;
    }
    //cout<<cnt1<<cnt2<<cnt3<<endl;
    sort(a,a+cnt1);
    sort(b,b+cnt2);
    sort(c,c+cnt3);
    if(cnt3+min(cnt1,cnt2)<k){
        cout<<-1<<endl;
        return 0;
    }
    if(cnt3==0){
        ll ans=0;
        for(int i=0;i<k;i++){
            ans+=(ll)a[i]+(ll)b[i];
        }
        cout<<ans<<endl;
    }
    else{
        ll ans=0;
        priority_queue<ll,vector<ll>,greater<ll> >q;
        for(int i=0;i<cnt3;i++) q.push((ll)c[i]);
        for(int i=0;i<min(cnt1,cnt2);i++){
            q.push((ll)a[i]+(ll)b[i]);
        }
        for(int i=0;i<k;i++){
            ans+=q.top();
            q.pop();
        }
        cout<<ans<<endl;
    }
    return 0;

}


猜你喜欢

转载自blog.csdn.net/xxxxxiao123/article/details/107020418