Codeforces Round #560 (Div. 3) (ALL)

本文记录了Codeforces Round #560 (Div. 3)的解题过程,涵盖A - F2等多道题目。包括数字翻转、比赛场次安排、字符串删除、数组判断、数组排序使结果最小以及商品购买天数计算等问题,并给出了相应的解题思路,如模拟、贪心、排序比对等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Codeforces Round #560 (Div. 3)

第一次补完一场cf

A:给数字A(由01组成的十进制)和b,c,求A%10^b=10^c最少要翻转A几位。

字符串瞎模拟一下即可。

#include<bits/stdc++.h>
using namespace std;
#define LL long long

int main(){
    int n,x,y;scanf("%d%d%d",&n,&y,&x);
    string s;cin>>s;int ans=0;
    for(int i=n-1;i>=n-y;i--){
        if(i==n-x-1)continue;
        if(s[i]!='0')ans++;
    }
    if(s[n-x-1]=='0')ans++;
    printf("%d",ans);
    return 0;
}

B:有n场比赛,第n天打多于n个问题的比赛,问怎么安排比赛使能打的比赛场次最多,求最多的场次。

multiset瞎搞即可

#include<bits/stdc++.h>
using namespace std;
#define LL long long
multiset<int>s;
int main(){
    int  n;scanf("%d",&n);for(int i=1;i<=n;i++){
        int sc;scanf("%d",&sc);s.insert(sc);
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        multiset<int>::iterator it;
        it=s.lower_bound(i);
        if(it!=s.end()){
            ans++;
            s.erase(it);
        }
    }
    printf("%d",ans);
    return 0;
}

C:给一个字符串,要求删除几个,使得第2*i位和第2*i-1位不一样,求最少删几个。

贪心从左往右删即可

#include<bits/stdc++.h>
using namespace std;
#define LL long long
string s;
bool vis[1000000];
int main(){
    int n;cin>>n>>s;
    int ans=0;
    for(int i=0;i<n-1;){
        int j;
        for(j=i+1;j<n;j++){
            if(s[i]==s[j]){ans++;vis[j]=1;}
            else {break;}
        }
        i=j+1;
    }
    if((ans+n)%2){ans++;}
    cout<<ans<<endl;int p=1;
    for(int i=0;i<n;i++){
        if(vis[i]==0&&p<=n-ans)cout<<s[i],p++;
    }
    return 0;
}

D:给一个数组,判断其是否为n的(almost all因子数组),almost all的因子数组是包含n所有因子(除1和n)的数组。

先sort,假设是满足题意的,那么第一个和最后一个数字相乘就是n,那么求出n的所有因子,再进行比对即可判断。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int MXN = 305;
LL gcd(LL x,LL y){
    if(y==0)return x;
    return gcd(y,x%y);
}
LL d[MXN];
vector<LL>v;
int main(){
    int T;cin>>T;while(T--){
        int n;scanf("%d",&n);for(int i=1;i<=n;i++){
            int sc;scanf("%d",&sc);d[i]=sc;
        }
        LL x=1;v.clear();
        sort(d+1,d+1+n);
        x=d[1]*d[n];
        for(LL i=2;i*i<=x;i++){
            if(x%i==0){
                v.push_back(i);
                v.push_back(x/i);
            }
        }
        if(v[v.size()-1]==v[v.size()-2])v.pop_back();
        sort(v.begin(),v.end());
        if(v.size()!=n){puts("-1");continue;}
        int k=0;
        for(int i=1;i<=n;i++){
            if(v[i-1]!=d[i]){k=1;break;}
        }
        if(k){puts("-1");continue;}
        printf("%lld\n",x);
    }
    return 0;
}

E:给两个数组A和B,B可以交换顺序,使得最小,其中

一开始没发现A不能动,真的zz  对于一个位置p,那么他对答案的贡献是要乘上p*(n+1-p),显然那么A乘上p*(n+1-p)再从小到大排序, B再重大到小排,这样一定使得答案最小。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int MXN = 1e6;
const int mod = 998244353;
LL a[MXN],b[MXN],c[MXN];
bool cmp(int x,int y){return x>y;}
int main(){
    int n;scanf("%d",&n);
    for(int i=1;i<=n;i++){
        LL tt=(LL)i*(LL)(n+1-i);
        scanf("%d",&a[i]);
        a[i]=a[i]*tt;
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&b[i]);
    }
    sort(a+1,a+1+n);sort(b+1,b+1+n,cmp);
    LL ans=0;
    for(int i=1;i<=n;i++){
        ans=ans+a[i]%mod*b[i]%mod;
        ans%=mod;
    }
    printf("%lld\n",ans);
    return 0;
}

F1和F2,F2数据大,直接写F2

F2:第i天有i元,要买n个东西,第i个东西要ki个,然后某几天会对某些商品打对折,求最少需要几天可以买到所有的东西。

二分第几天,然后贪心的攒钱,对于每一件商品都再最后一天去买,这样保证可以买到的打折商品数量最多。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pai acos(-1)
const LL  mod = 1000000007;
const int MXN = 5e5+5;
int k[MXN];int last[MXN],need[MXN],d[MXN],t[MXN];
vector<int>v[MXN];
bool check(int x,int n,int m){
    for(int i=1;i<=n;i++)need[i]=k[i],last[i]=0;
    for(int i=1;i<=x;i++)v[i].clear();//出错
    for(int i=1;i<=m;i++){
        if(d[i]<=x)
            last[t[i]]=max(last[t[i]],d[i]);//出错
    }
    for(int i=1;i<=n;i++){
        if(last[i]>0)
            v[last[i]].push_back(i);//第last[i]天有第i个物品
    }
    int money=0;
    for(int i=1;i<=x;i++){
        money++;
        for(auto it:v[i]){
            int lim=min(money,need[it]);
            money-=lim;need[it]-=lim;
        }
    }
    for(int i=1;i<=n;i++){money-=2*need[i];}
    return money>=0;
}
int main(){
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&k[i]);
    for(int i=1;i<=m;i++){scanf("%d%d",&d[i],&t[i]);}
    int l=0,r=4e5+10,ans=-1;
    while(l<=r){
        int mid=(l+r)/2;
        if(check(mid,n,m)){
            ans=mid;
            r=mid-1;
        }
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

细节啊细节,好菜啊......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值