CodeForces 135C C. Zero-One

来源:互联网 发布:js弹出框 编辑:程序博客网 时间:2024/06/05 06:21

题目

题意:

一个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-8using 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\n",i>>1,i&1);        //printf("\n");    }    return 0;}