題意:
交互題,他會告訴你有一個只有 0 和 1 的數組的長度 n,接下來你有不多餘15次操作:
“? str” ?是詢問操作,str就是你認爲這個數組的樣子,他會返回裏面錯了多少個,繼續循環,不能超過15次。
“! pos0 pos1”!是答案操作,pos0,pos1是你找到相鄰 0 和 1 的的下標,結束循環。
題解:
不能超過 15 次操作並且長度不會超過 1000,說明就可以二分出只有 0 和 1 的兩位區間。怎麼判斷區間有0和1呢?
當全取 0 的時候,得到的數就是區間內 1 的個數,同理,我們可以的到區間內 0 的個數。只要得到的數在全錯和全對範圍內就說明有 0 和 1 的存在,即:
答案:000101
000111 會得到 2,如果全錯會得到 3 ,全對會得到 0,這時候 0 <= 2 <= 3,所以裏面一定存在 0 和 1。
AC代碼:
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <stack>
#include <cmath>
#include <deque>
#include <queue>
#include <list>
#include <set>
#include <map>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define line printf("---------------------------\n")
#define mem(a, b) memset(a, b, sizeof(a))
#define pi acos(-1)
using namespace std;
typedef long long ll;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const int maxn = 1000+10;
int num1, n;
bool check(int l, int r) {
printf("? ");
for(int i = 0; i < l; i++) {
printf("0");
}
for(int i = l; i <= r; i++) {
printf("1");
}
for(int i = r + 1; i < n; i++) {
printf("0");
}
puts("");
fflush(stdout);
int num2;
cin >> num2;
if(num1 - (r - l + 1) < num2 && num2 < num1 + (r - l + 1)) {
return true;
} else {
return false;
}
}
int main() {
while(cin >> n) {
printf("? ");
for(int i = 0; i < n; i++) {
printf("0");
}
puts("");
fflush(stdout);
cin >> num1;
int l = 0, r = n - 1;
while(r - l >= 2) {
int mid = (l + r) >> 1;
if(check(mid, r)) {
l = mid;
} else {
r = mid;
}
}
printf("? ");
for(int i = 0; i < l; i++) {
printf("0");
}
printf("10");
for(int i = r + 1; i < n; i++) {
printf("0");
}
puts("");
fflush(stdout);
int temp;
cin >> temp;
if(num1 > temp) {
printf("! %d %d\n", r + 1, l + 1);
} else {
printf("! %d %d\n", l + 1, r + 1);
}
}
}