Description
Let’s play a game. You are given a row of n balls, each ball is either black or white. Their positions in a row are numbered from 1 to n. You know the total number of balls n, but have no information about the order of their colors. You don’t even know how many white balls are there.
You are allowed to make queries v u (1 ≤ v, u ≤ n). If the ball on position v is black and the ball on position u is white, then these two balls are swapped. Otherwise, nothing happens. Even if the balls are swapped, you don’t get any feedback.
After a number of queries (can be zero) you a required to make a “statement.” “Statement” also consists of two positions v, u. Your goal is to choose positions, that contain two balls of the same color.
In this problem we ask you to print both queries and a “statement”, that comes after them.
A single test can contain several games. Furthermore, all tests except the first one contain 99 game descriptions. In the first game n = 2, in the second — n = 3 … in the last game n = 100.
First test is the same as the sample below.
In all other tests your program must make the right statement at least in 80 games.
Note, that we do not guarantee that the tests are random.
Input
First line contains m — number of games in the test. For every test, except for the first one, m=99.
Remaining lines contain ciphered (except for the first test) order of balls in the row. Thus we guarantee, that the tests are determined beforehand and do not depend on your strategy. Please, do not try to use this data in any way and do not try to decipher it.
Output
Output m game descriptions.
One description consists of (k+1) lines, where k — number of queries made by your program.
First k lines should contain the queries in the following format: ? v u (1 ≤ v, u ≤ n, v ≠ u).
The last line should contain the “statement”: ! v u (1 ≤ v, u ≤ n, v ≠ u).
Total amount of lines (over all games in a test) should not exceed 5×105 .
题意
此题应该算是一种交互题
给定 m 组分别长度为 2, 3, 4, …, m的字符串 (你并不知道每个字符串是什么)。每个字符串的均只有 0
或 1
两种字符,且 0
, 1
个数未知,位置未知。要求在通过一定量的 ? v u
操作之后,请你给出一个 ! v u
表示你认为位置 v
与位置 u
的字符相同。此时机器会判断是否相同。当你的判断正确率超过 80% ,则获得 Accepted
!
操作 ? v u
表示若 v=1
且 u=0
,则位置上的字符做交换,其余任何情况均不做处理。
分析
要求输出的 ? v u
和 ! v u
总组数不能超过
5×105
。
由于 ? v u
操作是单向操作,结合排序可以想到,通过类似冒泡排序的做法可以将原字符串处理成 00...01...11
的形式。若对每组的结果均输出 ! i i+1
,则只有在字符 0
和 1
交界的位置会出现判断失误的情况,其他情况的判断均可正确。
由此,该题又变成了一个随机数的题目。每次输出的 ! i i+1
失败的概率为 1/(len(str)-1)
。因此打随机数正确率 80%
以上是很正常的事情。当然,也可从出题人的角度考虑,只有 21 组数据均卡同一个位置才会 WA 。此时我取了中间两个值,也能过。
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int m;
scanf("%d",&m); m++;
for(int n=2;n<=m;++n)
{
if(n==2) printf("! 1 2\n");
else{
for(int i=1;i<n;++i)
for(int j=i+1;j<=n;++j)
printf("? %d %d\n",i,j);
printf("! %d %d\n",n/2,n/2+1);
}
}
}