Edu Codeforces Round167 (Div2)--(A~D)题解

Problem - A - Codeforces

思路:当且仅当y<=-2是追不上的。

void solve(){                   A
    int x,y; cin>>x>>y;
    if(y<=-2) cout<<"NO"<<endl;
    else cout<<"YES"<<endl;
}

Problem - B - Codeforces

思路:因为不能破坏stra,所以只能在stra的左端或者右端添加字符,那么stra,strb相同的片段在strb中只能是连续的,不能拆开的,不然补不全。因此枚举strb连续的子串在stra中出现的最大长度即可。

void solve(){           B           写了44分钟。。stra,strb相同的片段在strb中只能是连续的,不能拆开的,不然是子序列也没用,补不全。   好好好...
    stra为子串,strb为子序列
    string stra,strb; cin>>stra>>strb;
    int na=stra.size(),nb=strb.size();
    int maxn=0;
    for(int i=0;i<nb;i++){
        int idx=i,cnt=0;
        for(int j=0;j<na;j++){
            if(stra[j]==strb[idx]) idx++,cnt++;
        }
        maxn=max(maxn,cnt);
    }
    cout<<na+nb-maxn<<endl;
}

Problem - C - Codeforces

思路:很明显的贪心。首先在1和0/-1之间,肯定先选1,在0和-1之间肯定先选0。当1和1,-1和-1,先记录下来,后面贪心再用。目标是让cura和curb尽量接近。所以like和hate是用来控制他们尽量接近的。要注意的是like==hate的时候,是不能跳过操作的。例如处理完输入完之后curb=100,cura=10,like=20,hate=20。这个时候hate大可以全给curb,like全给cura。这样可以得到ans=30。其他的情况也类似贪心即可。

int a[200005],b[200005];
void solve(){           C     贪心,注意细节
    int n; cin>>n;
    int cura=0,curb=0,like=0,hate=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    for(int i=1;i<=n;i++){                  数据的读入都错了。。直接cin>>a>>b了。。
        if(a[i]==1&&b[i]==1) like++;
        else if(a[i]==-1&&b[i]==-1) hate++;
        else if(a[i]==1) cura++;
        else if(b[i]==1) curb++;
    }
    if(cura>curb) swap(cura,curb);  cura<=curb
    if(like>hate){
//        like-=hate;              这样还不够贪心。如果dif很大很大,那么可以把hate给curb,like全给cura
        int dif=curb-cura;
        if(hate>=dif) curb=cura,hate-=dif;             尽量让cura==curb
        else curb-=hate,hate=0;
        like-=hate;
        dif=curb-cura;
        if(like>=dif) {
            like-=dif,cura=curb;
            cout<<cura+like/2<<endl;
        }
        else {
            cura+=like;
            cout<<min(cura,curb)<<endl;
        }
    }
    else if(hate>like){
//        hate-=like;           这样还不够贪心。如果dif很大很大,那么可以把hate给curb,like全给cura
        int dif=curb-cura;
        if(like>=dif) cura=curb,like-=dif;              尽量让cura==curb
        else cura+=like,like=0;
        hate-=like;
        dif=curb-cura;
        if(hate>=dif){
            hate-=dif,curb=cura;
            if(hate&1) cout<<cura-hate/2-1<<endl;
            else cout<<cura-hate/2<<endl;
        }
        else cout<<cura<<endl;
    }
    else if(hate==like){
        int dif=curb-cura;
        if(hate>=dif/2) cura+=dif/2,curb-=dif/2;
        else cura+=like,curb-=hate;
        cout<<min(cura,curb)<<endl;
    }
}

Problem - D - Codeforces

思路:排序+贪心。贪心地选dif更小的操作,输入时记录每一个dif,之后升序排序。要注意的是,暴力的跑是o(n*m)是肯定不行的。但是实际上同样数量的不同类型金属锭,是可以一起计算的。所以可以用一个桶cnt[i]来记录剩余数量为i的金属锭有几个。但是最大的金属锭数量是1e9,桶是不能记录的。但是最大的a只有1e6,所以可以记录小的mindif是多少,以及对应的a。在输入金属锭大小的时候,如果能冶炼金属a,那么直冶炼,这样保证所有金属锭数量<=1e6,桶是可以记录的。最后从1e6到1遍历cnt即可。

int n,m;
typedef struct node{
    int a,b,dif;
    bool operator < (const node &x) const{
        if(dif!=x.dif) return dif<x.dif;
        return a<x.a;
    }
}node;
node arr[1000006];
int cnt[1000006];
void solve(){                   D    排序+贪心
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>arr[i].a;
    for(int i=1;i<=n;i++) {
        cin>>arr[i].b;
        arr[i].dif=arr[i].a-arr[i].b;
    }
    sort(arr+1,arr+n+1);
    int ans=0,aa=arr[1].a,mindif=arr[1].dif;
    for(int i=1;i<=m;i++){
        int x; cin>>x;
        if(x>=aa){
            ans+=(x-aa)/mindif+1;
            x=x-((x-aa)/mindif+1)*mindif;
        }
        cnt[x]++;
    }
    int idx=1;
    for(int i=1e6;i>=1&&idx<=n;i--){
        if(cnt[i]){
            int x=i;
            while(x<arr[idx].a&&idx<=n) idx++;
            if(idx>n) break;
            aa=arr[idx].a,mindif=arr[idx].dif;
            ans+=((x-aa)/mindif+1)*cnt[i];
            x=x-((x-aa)/mindif+1)*mindif;
            cnt[x]+=cnt[i];
        }
    }
    cout<<ans*2<<endl;
}

抱歉,根据提供的引用内容,我无法理解你具体想要问什么问题。请提供更清晰明确的问题,我将竭诚为你解答。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Codeforces Round 860 (Div. 2)题解](https://blog.csdn.net/qq_60653991/article/details/129802687)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [【CodeforcesCodeforces Round 865 (Div. 2) (补赛)](https://blog.csdn.net/t_mod/article/details/130104033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Codeforces Round 872 (Div. 2)(前三道](https://blog.csdn.net/qq_68286180/article/details/130570952)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值