Codeforces Round #627 (Div. 3)


题目

A Yet Another Tetris Problem

问题:俄罗斯方块,只能用宽为1,高为2的木块,给初始高度,问是否可以全部消掉。
答案:当初始高度奇偶性全部相同的时候可以全部消掉。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[101];
int main(){
    ll t;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        bool flag=true;
        for(ll i=1;i<=n;i++){
            scanf("%lld",&a[i]);
        }
        for(ll i=2;i<=n;i++){
            if((a[i]&1)!=(a[i-1]&1)){
                flag=false;
                break;
            }
        }
        if(flag)puts("YES");
        else puts("NO");
    }
}

B Yet Another Palindrome Problem

问题:给一个序列,判断是否有长度大于等于3的子序列是回文串。
答案:判断是否有两个相等的数不相邻即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    ll t;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        map<ll,ll>mp;
        bool flag=false;
        for(ll i=1;i<=n;i++){
            ll x;
            cin>>x;
            if(mp[x]&&i-mp[x]>1)
                flag=true;
            if(!mp[x]){
                mp[x]=i;
            }
        }
        if(flag)
            puts("YES");
        else
            puts("NO");
    }
}

C Frog Jumps

问题:青蛙从0跳到n+1,在0时只能向左跳,给一个长为n的字符串,若第i位’R’则在i位置只能向右跳,若第i位为’L’则在i位置只能向左跳,每次条约距离不大于d,问最小的d是多少。
答案:最小的d为0到第一个’R’的距离,相邻’R’的距离,最后一个’R’到n+1的距离中的最小值。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    ll t;
    cin>>t;
    while(t--){
        string s;
        cin>>s;
        ll cur=0;
        ll MAX=0;
        for(ll i=0;i<s.size();i++){
            if(s[i]=='R'){
                MAX=max(MAX,i+1-cur);
                cur=i+1;
            }
        }
        MAX=max(MAX,s.size()+1-cur);
        cout<<MAX<<endl;
    }
}

D Pair of Topics

问题:给两个长度为n的序列a和b,问序列中满足 a i + a j > b i + b j a_i+a_j>b_i+b_j ai+aj>bi+bj的数对 < i , j > <i,j> <i,j>的数量。
答案:对a和b按位求差结果保存至c即c=a-b,计算c中 c i + c j > 0 c_i+c_j>0 ci+cj>0的数对 < i , j > <i,j> <i,j>的数量。从小到大排序,用lower_bound函数对每个数查找第一个大于当前位置的负数的位置,当前位置与该位置的差值与0的最大值即为当前位置对答案的贡献。复杂度 O ( n ∗ l o g 2 n ) O(n*log_2n) O(nlog2n)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+10;
ll a[maxn],b[maxn],c[maxn];
int main(){
    ll n;
    cin>>n;
    for(ll i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    for(ll i=1;i<=n;i++){
        scanf("%lld",&b[i]);
        c[i]=a[i]-b[i];
    }
    sort(c+1,c+1+n);
    ll ans=0;
    for(ll i=1;i<=n;i++){
        ll pos=upper_bound(c+1,c+1+n,-c[i])-c;
        ans+=max(0LL,i-pos);
    }
    cout<<ans<<endl;
}

E Sleeping Schedule

问题:一天h个小时,一个人总共谁n次觉,一次睡一天,第i次可以选择在上一次醒来后 a i a_i ai a i − 1 a_i-1 ai1个小时后开始睡,若其睡觉的时间为 [ l , r ] [l,r] [l,r],则他将拥有一次良好的睡眠,求他最多拥有良好的睡眠次数。
答案:dp求解,dp[i][j]表示前i次睡眠后在第j小时醒来的最多睡眠次数。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[2010][2010];
ll a[2010];
int main(){
    ll n,h,l,r;
    memset(dp,-1,sizeof(dp));
    cin>>n>>h>>l>>r;
    for(ll i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    dp[0][0]=0;
    for(ll i=1;i<=n;i++){
        for(ll j=0;j<h;j++){
            if(dp[i-1][(j-a[i]+h)%h]!=-1){
                if(j>=l&&j<=r){
                    dp[i][j]=max(dp[i][j],dp[i-1][(j-a[i]+h)%h]+1);
                }
                else{
                    dp[i][j]=max(dp[i][j],dp[i-1][(j-a[i]+h)%h]);
                }
            }
            if(dp[i-1][(j-a[i]+1+h)%h]!=-1){
                if(j>=l&&j<=r){
                    dp[i][j]=max(dp[i][j],dp[i-1][(j-a[i]+1+h)%h]+1);
                }
                else{
                    dp[i][j]=max(dp[i][j],dp[i-1][(j-a[i]+1+h)%h]);
                }
            }
        }
    }
    ll ans=0;
    for(ll i=0;i<h;i++){
        ans=max(ans,dp[n][i]);
    }
    cout<<ans<<endl;
}

F Maximum White Subtree

问题:给一棵树,根不确定,并将树上的每个点染成黑色和白色,求对于每个节点包含这个点的子树中白色点与黑色点的数量差最大为多少?
答案:换根dp,先任取一点为根,做普通的树形dp,u为v的父亲时 c n t [ u ] + = m a x ( 0 , c n t [ v ] ) cnt[u]+=max(0,cnt[v]) cnt[u]+=max(0,cnt[v])
之后再进行换根,一个点的答案除了其当前子树的贡献外,还包括不在当前子数中的点对它的贡献,将其父亲消除以这个点为根的字树后求父亲的当前状态,这个状态就是这个点除了字数外的点对其的贡献。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+10;
ll n;
ll a[maxn];
ll head[maxn];
ll cnt[maxn];
ll ans[maxn];
struct edge{
    ll v,next;
}e[maxn<<1];
ll CNT;
void add(ll u,ll v){
    e[CNT].v=v;
    e[CNT].next=head[u];
    head[u]=CNT++;
}
void dfs1(ll u,ll f){
    cnt[u]=a[u]?1:-1;
    for(ll i=head[u];~i;i=e[i].next){
        ll v=e[i].v;
        if(v==f)continue;
        dfs1(v,u);
        cnt[u]+=max(0LL,cnt[v]);
    }
}
void dfs2(ll u,ll f){
    ans[u]=cnt[u];
    for(ll i=head[u];~i;i=e[i].next){
        ll v=e[i].v;
        if(v==f)continue;
        cnt[u]-=max(0LL,cnt[v]);
        cnt[v]+=max(0LL,cnt[u]);
        dfs2(v,u);
        cnt[v]-=max(0LL,cnt[u]);
        cnt[u]+=max(0LL,cnt[v]);
    }
}
int main(){
    memset(head,-1,sizeof(head));
    cin>>n;
    for(ll i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    for(ll i=1;i<n;i++){
        ll u,v;
        scanf("%lld%lld",&u,&v);
        add(u,v);
        add(v,u);
    }
    dfs1(1,-1);
    dfs2(1,-1);
    for(ll i=1;i<=n;i++){
        printf("%lld%c",ans[i],i==n?'\n':' ');
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值