题解:CF2280B Secret String Patterns
题目大意
系统有一个长度为 01。
你可以向系统提问,每次询问一个区间 1 的个数。你最多只能询问
如果存在 01 子串,输出 ! YES,否则输出 ! NO。
思路
如果一个字符串中不存在 01 子串,那么它一定形如:
也就是说,所有的 1 都排在所有的 0 前面。
我们可以利用这个性质进行判断。假设整个字符串中 1 的总个数为
-
第一次询问:查询整个字符串
[1, n] ,得到1 的总个数k 。- 如果
k = 0 (全为0)或k = n (全为1),显然没有01,直接输出! NO。
- 如果
-
第二次询问:查询前缀区间
[1, k] 。- 如果这个区间里
1的个数严格小于k ,说明前k 个字符里混进了0。既然总共只有k 个1,那么后面必然有1来补齐总数,这意味着在某个0后面出现了1。直接输出! YES。
- 如果这个区间里
-
第三次询问:查询后缀区间
[k+1, n] 。- 如果这个区间里
1的个数大于0的个数,说明后n-k 个字符里混进了1。同理,因为前面已经用掉了一些1,这里如果还有1,说明前面必然有0。直接输出! YES。
- 如果这个区间里
-
如果以上两次检查都完全吻合(前
k 个全是1,后n-k 个全是0),说明字符串严格符合111...000的形式,不存在01,输出! NO。
故最多只需要进行
代码
找上述过程模拟即可。
#include<bits/stdc++.h>
using namespace std;
int query(int l,int r) {
cout<<"? "<<l<<" "<<r<<'\n';
int res;
cin>>res;
return res;
}
int main() {
int t;
cin>>t;
while(t--) {
int n;
cin>>n;
int k=query(1,n);
if(k==0||k==n) {
cout<<"! NO\n";
continue;
}
if(query(1,k)<k) {
cout<<"! YES\n";
continue;
}
if(query(k+1,n)>0) {
cout<<"! YES\n";
continue;
}
cout<<"! NO\n";
}
}
~点个赞吧~