码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #646 (Div. 2)题解

时间:2020-06-04 01:08:15      阅读:51      评论:0      收藏:0      [点我收藏+]

标签:cout   pac   names   tin   ret   ORC   sum   +=   return   

 Codeforces Round #646 (Div. 2)

A题

题意:给你一个数组,问是否能选出其中 x 个数使和为奇数

#include<bits/stdc++.h>
using namespace std;
#define forn(i,n) for(int i=0;i<n;i++)
#define forl(i,n) for(int i=1;i<=n;i++)
typedef long long ll;
const int maxn=5e5+10;
#define IO ios_base::sync_with_stdio(false)
const int inf=1e9;
const int inf=0x3f3f3f3f;

int main()
{
    IO;int t;cin>>t;
    while(t--)
    {
        int n,x;cin>>n>>x;
        int a[n+5],ans=0;
        forn(i,n)cin>>a[i];
        forn(i,n)if(a[i]&1)ans++;
        if(ans>=1&&!(x==n&&ans%2==0)&&!(ans==n&&x%2==0))puts("Yes");
        else puts("No");
    }
    return 0;
}
int main() { IO;int t;cin>>t; while(t--) { int n,x;cin>>n>>x; int a[n+5]; forn(i,n)cin>>a[i]; int cnt0=0,cnt1=0; int flag=0; forn(i,n){ if(a[i]&1)cnt1++; else cnt0++; } for(int i=1;i<=x;i+=2) if(cnt1>=i&&cnt0>=x-i)flag=1; if(flag)puts("Yes"); else puts("No"); } return 0; }

B题

题意:各一个 01串,问最少修改多少次可以使串不包含 子序列010 ,101

思路:

  1. 合法串只能为 前部分全0后部分全1 或者 前部分全1后部分全0./*000000,111111,000111,111000*/
  2. 所以可以枚举 01的分界点,然后用前缀和记录一下 01的数量就可以o(1)查询要修改多少次了
int main()
{
    IO;int t;cin>>t;
    while(t--)
    {
        string s;cin>>s;
        //int n=s.length();
        int n=s.size();
        int ans=inf;
        //vector<int>sum(n);
        int sum[n+5];
        for(int i=0;i<n;i++){
            if(i==0)sum[0]=(s[i]==1);///可以使1或0的前缀和
            else sum[i]=sum[i-1]+(s[i]==1);
        }
        int cnt0=0,cnt1=0;
        for(int i=n-1;i;i--){
            if(s[i]==0)cnt0++;
            else cnt1++;
            ans=min(ans,min(sum[i-1],i-sum[i-1])+min(cnt0,cnt1));///部分为1/0
        }
        ans=min(ans,min(sum[n-1],n-sum[n-1]));///全为1或全为0的情况
        cout<<ans<<endl;
    }
    return 0;
}

int main()
{
    IO;int t;cin>>t;
    while(t--)
    {
        char s[maxn];cin>>s+1;
        int n=strlen(s+1);
        int ans=inf;
        int pre0[n+5],pre1[n+5];
        for(int i=1;i<=n;i++){
            pre0[i]=pre0[i-1]+(s[i]==0);
            pre1[i]=pre1[i-1]+(s[i]==1);
        }
        for(int i=1;i<=n;i++){
            ans=min(ans,pre0[i-1]-pre0[0]+pre1[n]-pre1[i-1]);
            ans=min(ans,pre1[i-1]-pre1[0]+pre0[n]-pre0[i-1]);
        }
        cout<<ans<<endl;
    }
    return 0;
}

C题

题意:给一棵树,A和B玩游戏,每次可以拿走一个叶子节点,A先手,谁最后拿到 x节点 谁就获胜,两人都想赢,问最后谁能赢得游戏

思路:

1.可以以 x为根节点来考虑这个问题,考虑一下最后的状态,最后的状态一定是 x的出度为 1 (也就是与 x相连的只有一个节点了),因为这时候 x才能成为叶子节点,才能有人获胜

2.那么我们就只要考虑到达最后状态前 一共需要拿走多少个节点就好了,一人那一个,判断奇偶性就能得出答案,偶A赢,奇B赢

3.考虑一共要拿走多少节点,如果与 x直接相连的只有一个节点,那需要拿走的是 0 ,一定是 A赢。如果不止一个,那就要拿到最后只剩 x节点和它的一个子节点才能获胜,那么需要拿走 (n-2)个节点

int main()
{
    IO;int t;cin>>t;
    while(t--)
    {
    int n,x;cin>>n>>x;
    int u,v,cnt=0;
    int k=n-2;
    for(int i=1;i<n;i++){
        cin>>u>>v;
        if(u==x||v==x)cnt++;
    }
    if(cnt<=1){puts("Ayush");continue;}
    if(k&1)puts("Ashish");
    else puts("Ayush");
    }
    return 0;
}

 

Codeforces Round #646 (Div. 2)题解

标签:cout   pac   names   tin   ret   ORC   sum   +=   return   

原文地址:https://www.cnblogs.com/angelliu/p/13040906.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!