题意:
一个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; }