CodeForces 135C C. Zero-One

题目

题意:

一个01串,AB两个人轮流删去一个字符,直到只剩两个,A先手。最后剩的两位组成一个二进制数,A要使其最小,B要使其最大。

有一些部分不知道原来是什么,用?表示,求所有的可能里,最后剩下的两个字符。

题解:

我太弱了,WA了好几次,只有110组数据,我错在了107……


首先两人的最优策略都是从左到右删,A先删1,B先删0.

如果串长度为奇数,则A可以多删一次1.所以要先减去。

假如原串可能1多于0或0多余1,就可能剩下11和00.

如果1和0数量可能相等,按照1和0可以出现的最后的位置确定能否剩下01和10.

//Time:62ms
//Memory:200KB
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <set>
#define MAXN 200010
#define INF 1000000007
#define MP(x,y) make_pair(x,y)
#define FI first
#define SE second
#define EPS 1e-8
using namespace std;
char str[MAXN];
int vi[10]={0};
int main()
{
    while(scanf("%s",str)==1)
    {
        memset(vi,0,sizeof(vi));
        int cn[3]={0},len,pos[2]={-1,-1};
        len=strlen(str);
        for(int i=0;str[i];++i)
            if(str[i]=='0') ++cn[0],pos[0]=i;
            else    if(str[i]=='1') ++cn[1],pos[1]=i;
            else    ++cn[2];
        if(len&1)
            if(cn[1])
                --cn[1];
            else    if(cn[2])   --cn[2];
        if(cn[2]+cn[0]>cn[1])   vi[0]=1;
        if(cn[2]+cn[1]>cn[0])   vi[3]=1;
        if(abs(cn[0]-cn[1])<=cn[2])
        {
            if(cn[0]<len/2)   vi[(pos[1]<len-1)?2:1]=1;
            if(cn[1]<len/2)   vi[(pos[0]<len-1)?1:2]=1;
            if(cn[2]==0)
                if(pos[1]>pos[0])   vi[1]=1;
                else    vi[2]=1;
        }
        for(int i=0;i<4;++i)
            if(vi[i])
                printf("%d%d
",i>>1,i&1);
        //printf("
");
    }
    return 0;
}


原文地址:https://www.cnblogs.com/riskyer/p/3249391.html