1 条题解
-
2
发现0000,00000很多个0在一起肯定可以内部消化,那必须是101这种把0包围的情况才会NO,那是不是只有101010这种奇数给10的情况才可以no,我们会发现“左”101010“右”,中左,右,中的0可能会将101010中其中一个10给消除那可以成了必定yes的情况,思考了一下,如果101010...中10的个数是奇数,那我左中的0和10101010中一个10配对,那剩下来的偶数给10是不是可以俩俩配对,如果本来就是偶数给那本来就可以俩俩配对,我举个例子0.101010第一个0可以和第一个10配对,那剩下来2个10配对,那就是yes,那我们就永远都是yes, 右也一样,那我就找什么时候是no,那是不是左边没有0和10配对,然后右边也没有0和10配对,并且有奇数个10,那就是no,那我们分析分析情况是不是1.101010.11这种情况因为左边最后一个是1就行,那前面的0就根本配对不上10了,但是右边必须2个1,因为如果是10,那他本身就是10101010里面的,而且不能右边第一个是1,所以必须是11开头,所以我们找1“101010....”11这种字串就行了,然后判断10是不是奇数,如果是就是no,然后我们会发现如果101010串在开头的话其实也可以,没必要1.101010,因为我们第一个1是害怕左边的0和10配对,那左边没有0了,其实就没必要有这个1了,那我们可以特判开头是1010串的情况,但是右边就复杂了,必须至少有1个1,正常是2个,因为如果没有右边的数那是不是就是左.10101010这种情况,那后面那个0是不是可以随意分配,如果有奇数个10那最后那个0就自己配对,如果是偶数个那就俩俩配对,就一定是yes,所以必须有一个1,所以特判最后一个是1的情况也是可以的,那我们可以这样找如果在中间那找..1.101010.11..这种情况,如果是左开头那就找101010.11...这种情况,如果是结尾那找1.101010.1这种情况,(这样可以写,就是多加2个判断),那可以简单一点,是不是那几种情况可以合并,是不是只要在0和n+1的位置上加1就行了,这样不管开头和结尾都找1.10101010.11就行了。(如果原来开头就是1.101010,你会发现没有影响11.101010,也是1.101010,后面呢原来就是101010.11,那我后面加一个1变成101010,111,是不是也是101010.11,那很好了可以这样写了)(不满足条件,可以跳过,我们只判断是这种结构的10的个数)
void sll() { int n; cin>>n; string s; cin>>s; s='1'+s+'1'; int jl=0; int k=0; for(int i=0;i<=n+1;i++) { if(s[i]=='1'&&s[i+1]=='1'&&s[i+2]=='0') { k=1; if(s[i+3]=='1'&&i+3==n) { jl=1; } int j=i+3; if(s[j]=='1'&&s[j+1]=='1') { if(k%2==1) { jl=1; } } while(s[j]=='1'&&s[j+1]=='0') { k++; j+=2; if(s[j]=='1'&&s[j+1]=='1') { if(k%2==1) { jl=1; break; } } } i=j-3; } } if(jl==1) { cout<<"NO"<<'\n'; } else { cout<<"YES"<<'\n'; } } signed main() { ios::sync_with_stdio(0); cout.tie(0),cin.tie(0); int cs=1; cin>>cs; while(cs--) { sll(); } return 0; }
- 1
信息
- ID
- 1194
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- (无)
- 递交数
- 53
- 已通过
- 3
- 上传者