Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1)补题


题目

A - CME

#include<bits/stdc++.h>
using namespace std;
int main(){
int q;
scanf("%d",&q);
while(q--){
    int n;
    scanf("%d",&n);
    if(n&1)cout<<1<<endl;
    else if(n==2)cout<<2<<endl;
    else cout<<0<<endl;
}
}

B - Strings Equalization

#include<bits/stdc++.h>
using namespace std;
bool vis[26];
int main(){
    int n;
    scanf("%d",&n);
    while(n--){
        string s1,s2;
        cin>>s1>>s2;
        memset(vis,false,sizeof(vis));
        for(int i=0;i<s1.size();i++){
            vis[s1[i]-'a']=true;
        }
        bool flag=false;
        for(int i=0;i<s2.size();i++){
            if(vis[s2[i]-'a'])
                flag=true;
        }
        if(flag)puts("YES");
        else puts("NO");
    }
}

C - Save the Nature

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e5+10;
ll t;
ll n;
ll arr[maxn];
ll a,b,x,y,s;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
}
ll lcm(ll x,ll y){
    return x*y/gcd(x,y);
}
bool check(ll mid){
    if(mid==0)return false;
    if(mid==n+1)return true;
    ll ans=0;
    ll cur=n;
    ll X[4];
    ll P[4];
    X[0]=mid/lcm(a,b);
    if(y>x)swap(x,y),swap(a,b);
    X[1]=mid/a-X[0];
    X[2]=mid/b-X[0];
    X[3]=mid-X[0]-X[1]-X[2];
    P[0]=x+y;
    P[1]=x;
    P[2]=y;
    P[3]=0;
    for(ll i=0;i<4;i++){
        while(X[i]--){
        ans+=arr[cur--]*P[i]/100;
        }
    }
    return ans>=s;
}
int main(){
    scanf("%lld",&t);
    while(t--){
        scanf("%lld",&n);
        for(ll i=1;i<=n;i++){
            scanf("%lld",&arr[i]);
        }
        sort(arr+1,arr+1+n);
        scanf("%lld%lld%lld%lld%lld",&x,&a,&y,&b,&s);
        ll l=0,r=n+1;
        while(r-l>1){
            ll mid=(l+r)>>1;
            if(check(mid))r=mid;
            else l=mid;
        }
        printf("%lld\n",r==n+1?-1:r);
    }
}

D - Sequence Sorting

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3e5+10;
int L[maxn],R[maxn];
int a[maxn];
int dp[maxn];
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
 
        int n;
        int cnt;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            L[i]=R[i]=0;
        }
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            if(!L[a[i]])
                L[a[i]]=i;
                R[a[i]]=i;
        }
        sort(a+1,a+1+n);
        cnt=unique(a+1,a+n+1)-a-1;
        int MAX=0;
        for(int i=1;i<=cnt;i++){
            if(L[a[i]]<R[a[i-1]])
                dp[i]=1;
            else
                dp[i]=dp[i-1]+1;
            MAX=max(MAX,dp[i]);
        }
        printf("%d\n",cnt-MAX);
    }
}

E - Paint the Tree

对于一棵树每个点最多可以连k条边,使总权值最大,树形 dp,第二维代表是否与父亲连边

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=5e5+10;
ll head[maxn];
ll dp[maxn][2];
struct Edge{
    ll w,v,next;
}e[maxn<<1];
ll cnt;
void add(ll u,ll v,ll w){
    e[cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
ll n,k;
void dfs(ll u,ll f){
    ll tot=0;
    vector<ll>vec;
    for(ll i=head[u];~i;i=e[i].next){
        ll v=e[i].v;
        if(v==f)continue;
        dfs(v,u);
        tot+=dp[v][0];
        vec.push_back(dp[v][1]+e[i].w-dp[v][0]);
    }
    sort(vec.rbegin(),vec.rend());
    for(ll i=0;i<min(k,(ll)vec.size());i++){
        if(vec[i]>0)
            tot+=vec[i];
    }
    dp[u][0]=dp[u][1]=tot;
    if(vec.size()>=k&&vec[k-1]>0)
        dp[u][1]-=vec[k-1];
}
int main(){
    ll t;
    scanf("%lld",&t);
    while(t--){
 
        cnt=0;
        scanf("%lld%lld",&n,&k);
        for(ll i=1;i<=n;i++)
            head[i]=-1;
        for(ll i=1;i<n;i++){
            ll u,v,w;
            scanf("%lld%lld%lld",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        dfs(1,-1);
        printf("%lld\n",dp[1][0]);
    }
}
发布了28 篇原创文章 · 获赞 4 · 访问量 616

猜你喜欢

转载自blog.csdn.net/qq_44290978/article/details/104083345