Codeforces Round #646 (Div. 2)

A:http://codeforces.com/contest/1363/problem/A

题意:

n个数,能否从中找到x个数,使得sum为奇数

解析:

比赛时被自己弄吐了,懒得一个一个分析,索性直接暴力枚举

这破代码。。。各位不要学我啊。。。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1e3+10;
int a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,x;
        cin>>n>>x;
        int j=0,o=0;
        for(int i=1;i<=n;i++)
        {
            int md;
            cin>>md;
            if(md%2)
                j++;
            else
                o++;
        }
        if(j==0)
        {
            cout<<"NO"<<endl;
        }
        else if(o==0)
        {
            if(x%2)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
        else
        {
            if(x%2==0)
            {
                int ok=0,jj=1,oo=0;
                while(jj<=j)
                {
                    if((x-jj)<=o&&jj%2!=0)
                    {
                        ok=1;break;
                    }
                    else
                    {
                        jj++;
                    }
                }
                if(ok)
                    cout<<"YES"<<endl;
                else
                    cout<<"NO"<<endl;
            }
            else
            {
                if(j>=x)
                    cout<<"YES"<<endl;
                else
                {
                    int jj=1;
                    int ok=0;
                    while(jj<=j)
                    {
                        if(jj%2!=0&&(x-jj)<=o)
                        {
                            ok=1;break;
                        }
                        jj++;
                    }
                    if(ok)
                        cout<<"YES"<<endl;
                    else
                        cout<<"NO"<<endl;
                }
            }
        }
    }
}

正经解析:

其实不合法只有这三种情况:

1:奇数数为0

2:偶数数为0,x为偶数

3:x==n,sum%2==0

x<n&&j>0&&o>0是一定可以的,一定可以凑出奇数和来

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e3+10;
int a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,x;
        cin>>n>>x;
        int sum=0,j=0;
        for(int i=1;i<=n;i++)
        {
            int md;
            cin>>md;
            sum+=md;
            if(md%2)
                j++;
        }
        int o=n-j;
        if((x==n&&sum%2==0)||(j==0)||(o==0&&x%2==0))
            cout<<"NO"<<endl;
        else
            cout<<"YES"<<endl;
    }
}

B:http://codeforces.com/contest/1363/problem/B

题意:

给出的串,要把它变成不含010,101的串来(非连续子串),操作是反转0/1,求最小操作数

解析:

只有四种情况合法:

全0:000000....

全1:11111111...

先全1,后全0:111111....000000.....

先全0,后全1:00000.....111111......

数据很小,所以可以暴力枚举每一种情况:156ms

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1e3+10;
int a[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        string s;
        cin>>s;
        int len=s.length();
        if(len==1||len==2)
        {
            cout<<"0"<<endl;continue;
        }
        int cnt=0;
        for(int i=1;i<len;i++)
        {
            if(s[i]!=s[i-1])
                cnt++;
        }
        int cnt1=0,cnt0=0;
        for(int i=0;i<len;i++)
        {
            if(s[i]=='1')
                cnt1++;
            else
                cnt0++;
        }
        if(cnt==1||cnt==0||cnt1==0||cnt0==0)
        {
            cout<<"0"<<endl;continue;
        }        
        int minn=min(cnt1,cnt0);//00110
        for(int i=0;i<len;i++)
        {
            int sum=0;
            for(int j=i;j>=0;j--)
            {
                if(s[j]=='0')
                    sum++;
            }
            for(int j=i+1;j<len;j++)
            {
                if(s[j]=='1')
                    sum++;
            }
        //    cout<<i<<sum<<endl;
            minn=min(minn,sum);
        }
        for(int i=0;i<len;i++)
        {
            int sum=0;
            for(int j=i;j>=0;j--)
            {
                if(s[j]=='1')
                    sum++;
            }
            for(int j=i+1;j<len;j++)
            {
                if(s[j]=='0')
                    sum++;
            }
        //    cout<<i<<sum<<endl;
            minn=min(minn,sum);
        }
        cout<<minn<<endl;
    }
}

赛后反思:

假如数据很大,就需要优化,对于第3,4情况,反转数实际上是某个位置之前的0数目+之后的1数目/之前的1数目+之后的0数目

所以这里可以用前缀和处理一下:46ms,可以说是快多了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e3+10;
int s1[maxn],s0[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        string s;
        cin>>s;
        memset(s1,0,sizeof(s1));
        memset(s0,0,sizeof(s0));
        int len=s.length();
        if(len==1||len==2)
            cout<<"0"<<endl;
        else
        {
            if(s[0]=='0')
                s0[0]++;
            else
                s1[0]++;
            for(int i=1;i<len;i++)
            {
                s0[i]=s0[i-1];
                s1[i]=s1[i-1];
                if(s[i]=='0')
                    s0[i]++;
                else
                    s1[i]++;
            }    
            int minn=min(s1[len-1],s0[len-1]);
            for(int i=0;i<len;i++)
            {
                minn=min(minn,s1[i]+s0[len-1]-s0[i]);
                minn=min(minn,s0[i]+s1[len-1]-s1[i]);
            }
            cout<<minn<<endl;
        }
    }
}

C:http://codeforces.com/contest/1363/problem/C

题意:

n个结点,n-1条边,只能拿掉入度为0/1的点,谁先拿到x,谁赢。

解析:

当x入度为0/1的时候,直接先手胜

由于两个人都很聪明,每一步都要按最优来处理,所以谁都不想让对方赢,谁都不愿意先去靠近x,所以要把x点留到最后,即x入度==1的时候,这个时候,就确定了胜负了。

所以看一下,除了x之外的n-1个点的奇偶性,当然也可以看n-2的奇偶性,这个无所谓的。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e3+10;
int d[maxn];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n , x;
        memset(d,0,sizeof(d));
        cin>>n>>x;
        for(int i=1;i<n;i++)
        {
            int l,r;
            cin>>l>>r;
            d[l]++;
            d[r]++;
        }
        if(d[x]==0||d[x]==1)
            cout<<"Ayush"<<endl;
        else if((n-1)%2==0)
            cout<<"Ashish"<<endl;
        else
            cout<<"Ayush"<<endl;
    }
}
原文地址:https://www.cnblogs.com/liyexin/p/13026148.html