Codeforces Round 996 (Div. 2) B~D

B. Crafting

链接:Problem - B - Codeforces

算法:贪心

思路:因为每种材料都需要有对应的数量,所以直接将原材料数量减去所需数量,判断有多少不够的,也就是当前数量为负数的材料,因为合成材料需要所有其他材料每种各一个,所以当不够的材料超过两个的时候是不符合的,不够的材料为0的时候符合要求,不够的材料为1的时候,再判断其他所有材料是否够合成

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9 + 7;
ll a[Q],b[Q];
void solve(){
    ll n;cin>>n;
    for (ll i = 1; i <= n; i++){
        cin>>a[i];
    }
    ll cnt=0;ll p=0;
    for (ll i = 1; i <= n; i++){
        cin>>b[i];
        a[i]-=b[i];
        if(a[i]<0) cnt++,p=a[i];
    }
    if(cnt>=2){
        cout<<"NO\n";
        return;
    }
    if(cnt==0){
        cout<<"YES\n";
        return;
    }
    for (ll i = 1; i <= n; i++)
    {
        if(a[i]>=0 and a[i]<-p){
            cout<<"NO\n";
            return;
        }
    }
    cout<<"YES\n";
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll _ = 1;cin>>_;
    while(_--){
        solve();
    }
    return 0;
}

C. The Trail

链接:Problem - C - Codeforces

算法:模拟

思路:先求出当前每行每列的元素和,然后从起点1,1开始为每个位置赋值,若当前位置往下走也就是为D的时候,上一行的总和也就确认了,若当前位置往右走也就是为R的时候,左一行的总和也就确认了,S为每行的总和,因为我们需要 S⋅n=S⋅m S⋅n=S⋅m ,而由于 n≠m ,所以 S=0 ,如果当前为往下则当前位置的值也就是这一行的负总和,从而使得当前行为0,列同理。

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll Q = 1000 + 9;
const ll MOD = 1e9 + 7;
ll a[Q][Q];
ll h[Q],l[Q];
void solve(){
    ll n,m;cin>>n>>m;
    string s;cin>>s;s+='R';
    for (ll i = 1; i <= n; i++){
        for (ll j = 1; j <= m; j++){
            cin>>a[i][j];
        }
    }
    for (ll i = 0; i <= n; i++)
    {
        h[i]=0;
    }
    for (ll i = 0; i <= m; i++)
    {
        l[i]=0;
    }
    
    for (ll i = 1; i <= n; i++){
        for (ll j = 1; j <= m; j++){
            h[i]+=a[i][j];
        }
    }
    for (ll i = 1; i <= m; i++){
        for (ll j = 1; j <= n; j++){
            l[i]+=a[j][i];
        }
    }
    ll x=1,y=1;ll now=0;
    while (now<s.size())
    {
        if(s[now]=='R'){
            a[x][y]=-l[y];
            h[x]+=-l[y];
            y++;
        }else{
            a[x][y]=-h[x];
            l[y]+=-h[x];
            x++;
        }
        now++;

    }
    for (ll i = 1; i <= n; i++){
        for (ll j = 1; j <= m; j++){
            cout<<a[i][j]<<" ";
        }cout<<"\n";
    }

}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll _ = 1;cin>>_;
    while(_--){
        solve();
    }
    return 0;
}

D. Scarecrow

链接:Problem - D - Codeforces

算法:模拟

思路:模拟,首先判断第一个位置的稻草人,第一个位置的稻草人必须需要移动到0,记录当前过去了多长时间ans和移动后的位置now,然后乌鸦当前的位置在0+k,再进行判断后面的每个稻草人,①若后续每个稻草人在乌鸦当前位置的前面,当前时间已经过去了ans单位,所以当前稻草人可以往后移动ans个位置,让稻草人尽可能往当前乌鸦的位置接近或重合,②若稻草人在乌鸦当前位置的后面,当前时间已经过去了ans单位,所以当前稻草人可以往前移动ans位置,若ans个位置到不了稻草人当前的位置,则花费稻草人移动后的位置和乌鸦当前位置的一半时间去移动前后两个稻草人,使得后一个稻草人可以和乌鸦重合,移动到后一个稻草人+k的位置,一直到最后一个稻草人。

若到最后一个稻草人还未到达终点,则需要终点减当前位置个时间单位。

代码:

#include<bits/stdc++.h>
#define float double
using namespace std;
using ll = long long;
const ll Q = 2e5 + 9;
const ll MOD = 1e9 + 7;
float a[Q];
void solve(){
    ll n,k,m;cin>>n>>k>>m;
    for (ll i = 1; i <= n; i++){
        cin>>a[i];
    }
    float now=0;//当前位置
    float ans=0;//消耗的时间
    ans+=a[1];
    now=k;
    for (ll i = 2; i <= n; i++)
    {
        if(now>=m) break;
        // cout<<now<<" "<<ans<<"\n";
        if(a[i]>now){
            float tp=a[i]-now;
            if(ans>=tp){
                a[i]=now;
                now=a[i]+k;
            }else{
                a[i]-=ans;
                tp=a[i]-now;
                ans+=tp/2.0;
                a[i]-=tp/2.0;
                now+=tp/2.0;
                now+=k;
            }
        }else{
            float tp=now-a[i];
            if(ans>=tp){
                a[i]=now;
                now+=k;
            }else{
                a[i]+=ans;
                now=a[i]+k;
            }
        }
    }
    if(now<m){
        ans-=now;
        ans+=m;
    }
    cout<<int(ans*2)<<"\n";
    
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    ll _ = 1;cin>>_;
    while(_--){
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值