Codeforces Round 901 (Div. 2)

Problem - A - Codeforces

贪心

每次都先让b减到1,然后再去选择工具来增加时间

AC代码:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=110;
int x[N];
int a,b,n;
void solve() {
    cin>>a>>b>>n;
    for(int i=1;i<=n;i++) cin>>x[i];
    sort(x+1,x+1+n);
    int ans=0;
    for(int i=1;i<=n;i++){
        ans+=b-1;
        b=1;
        b=min(b+x[i],a)-1;
        ans++;
    }
    ans+=b;
    cout<<ans<<endl;
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
    cin>>t;
    while(t--) {
        solve();
    }
    return 0;
}

Problem - B - Codeforces

一开始只记录a,b的最小值和最大值,没有考虑到a的最小值去换b的最大值,然后b的最小值去换a的最大值时可能b的最小值不是刚换过来的a的最小值

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=55;
int a[N],b[N];
int n,m,k;
void solve() {
    cin>>n>>m>>k;
    int mina=2e9,minb=2e9;
    int maxa=0,maxb=0;
    int ans=0;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        ans+=a[i];
        mina=min(mina,a[i]);
        maxa=max(maxa,a[i]);
    }
    for(int i=1;i<=m;i++){
        cin>>b[i];
        minb=min(minb,b[i]);
        maxb=max(maxb,b[i]);
    }
    if(mina>=maxb){
        if(k%2==0) ans=ans-maxa+minb;
    }
    else{
        if(k%2==1) ans=ans-mina+maxb;
    }
    cout<<ans<<endl;
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
    cin>>t;
    while(t--) {
        solve();
    }
    return 0;
}

最优策略就是用最小值去换最大值

可以模拟第一回合和第二回合的情况,这样就涵盖了所有的情况了,当k为奇数时,和第一回合答案一样,当k为偶数时,和第二回合答案一样

AC代码:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=55;
int a[N],b[N];
int n,m,k;
void solve() {
    cin>>n>>m>>k;
    int ans1=0,ans2=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=m;i++) cin>>b[i];
    sort(a+1,a+1+n);
    sort(b+1,b+1+m);
    if(a[1]<b[m]){
        swap(a[1],b[m]);
        sort(a+1,a+1+n);
        sort(b+1,b+1+m);
    }
    for(int i=1;i<=n;i++) ans1+=a[i];
    if(b[1]<a[n]) swap(b[1],a[n]);
    for(int i=1;i<=n;i++) ans2+=a[i];
    if(k%2==1) cout<<ans1<<endl;
    else cout<<ans2<<endl;
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
    cin>>t;
    while(t--) {
        solve();
    }
    return 0;
}

Problem - C - Codeforces

如果用小数做的话,由于数过于大,会有精度问题

错误代码:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
int n,m;
void solve() {
    cin>>n>>m;
    if(n%m==0){
        cout<<0<<endl;
        return;
    }
    if(n>m) n%=m;
    double x=(double)n/m;
    double y=0.5;
    if(x<y) swap(x,y);
    double diff;
    if(x!=y) diff=x-y;
    else diff=x;
    while(diff>0.5){
        if(x<y) swap(x,y);
        diff=x-y;
        x-=y;
    }
    double d=0.5;
    while(d>0){
        d-=diff;
    }
    if(d!=0){
        cout<<-1<<endl;
        return;
    }
    int cnt=0;
    for(double i=1;;i/=2){
        if(i==diff) break;
        cnt++;
    }
    int ans=0;
    for(int i=1;i<=cnt-1;i++){
        ans+=n;
        n*=2;
    }
    ans+=m/2;
    cout<<ans<<endl;
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
    cin>>t;
    while(t--) {
        solve();
    }
    return 0;
}

f(n,m)表示n个苹果均分给m个人的次数

由于m最大1e9,n最小为1,所以最多log1e9次,大概30次

AC代码:

#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
int n,m;
void solve() {
    cin>>n>>m;
    n%=m;
    int ans=0;
    int cnt=0;
    while(n){
        ans+=n;
        n*=2;
        n%=m;
        cnt++;
        if(cnt>30) break;
    }
    if(n%m){
        cout<<-1<<endl;
        return;
    }
    cout<<ans<<endl;
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t=1;
    cin>>t;
    while(t--) {
        solve();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值