[CF2160D]D - MAD Interactive Problem题解
time limit per test
2 seconds
memory limit per test
256 megabytes
This is an interactive problem.
There is a secret sequence a1,a2,…,a2n−1,a2n, which contains each integer from 1 to n exactly twice.
Your task is to guess the sequence by using queries of the following type:
- "? kj1j2…jk" — select the integer k (1≤k≤2n) and k distinct indices j1,j2,…,jk (1≤j1,j2,…,jk≤2n). In response to the query, the jury will return MAD([aj1,aj2,…,ajk]).
We define the MAD (Maximum Appearing Duplicate) of an integer sequence as the largest integer that appears at least twice. Specifically, if there is no number that appears at least twice, the MAD value is 0. Some examples are as follows:
- MAD([1,2,1])=1;
- MAD([2,2,3,3])=3;
- MAD([1,2,3,4])=0.
Please identify the secret sequence using at most 3n queries.
有道 翻译
这是一个互动的问题。
有一个秘密序列 a1,a2,…,a2n−1,a2n ,它包含了从 1 到 n 的每一个整数两次。
你的任务是通过使用以下类型的查询来猜测序列:
——”? kj1j2…jk " -选择整数 k ( 1≤k≤2n )和 k 不同的索引 j1,j2,…,jk ( 1≤j1,j2,…,jk≤2n )。作为对查询的响应,陪审团将返回 MAD([aj1,aj2,…,ajk]) 。
我们将整数序列的 MAD (Maximum appear Duplicate)定义为至少出现两次的最大整数。具体来说,如果没有数字至少出现两次,则 MAD 值为 0 。一些例子如下:
-
MAD([1,2,1])=1 ;
-
MAD([2,2,3,3])=3 ;
—— MAD([1,2,3,4])=0 。
请最多使用 3n 次查询来确定秘密序列。
Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤3000). The description of the test cases follows.
The first line of each test case contains one integer n (2≤n≤300).
It is guaranteed that the sum of n2 over all test cases does not exceed 105.
After you read this line of input, the interaction begins with your first query.
有道 翻译
输入** **
每个测试包含多个测试用例。第一行包含测试用例的数量 t ( 1≤t≤3000 )。下面是测试用例的描述。
每个测试用例的第一行包含一个整数 n ( 2≤n≤300 )。
保证所有测试用例 n2 的总和不超过 105 。
在您阅读了这行输入之后,交互从您的第一个查询开始。
Interaction
To make a query, output a line (without quotes) in the following format:
- "? kj1j2…jk" (1≤k≤2n, 1≤j1,j2,…,jk≤2n)
Here, the indices j1,j2,…,jk which you selected must be pairwise distinct.
Then, after each query, read a single integer — the answer to your query.
You can make at most 3n queries of this type.
If your program has found the sequence a, print the line (without quotes) in the following format:
- "! a1a2…a2n−1a2n" (1≤ai≤n)
Note that this does not count towards the query limit.
After this, proceed to the next test case, or exit if this is the last test case.
The interactor in this task is not adaptive. In other words, the sequence a does not change during the interaction.
If you make more than 3n queries during an interaction, your program must terminate immediately, and you will receive the Wrong Answer verdict. Otherwise, you can get an arbitrary verdict because your solution will continue to read from a closed stream.
After printing each line, do not forget to output the end of line and flush the output buffer. Otherwise, you will receive the Idleness Limit Exceeded verdict. To flush, use:
- fflush(stdout) or cout.flush() in C++;
- System.out.flush() in Java;
- stdout.flush() in Python;
- see the documentation for other languages.
Hacks
To make a hack, please use the following format:
The first line should contain the number of test cases t (1≤t≤3000).
The first line of each test case should contain an integer n (2≤n≤300).
The following line should contain 2n integers a1,a2,…,a2n (1≤ai≤n). Each number from 1 through n must appear exactly twice.
The sum of n2 over all test cases should not exceed 105.
For example, the hack format corresponding to the example interaction is as follows.
2 2 2 2 1 1 2 1 2 1 2
有道 翻译
** **进行交互
要执行查询,以以下格式输出一行(不带引号):
——”?" ( 1≤k≤2n , 1≤j1,j2,…,jk≤2n )
这里,您选择的索引 j1,j2,…,jk 必须是成对不同的**。
然后,在每个查询之后,读取单个整数——查询的答案。
您最多可以执行这种类型的 3n 查询。
如果你的程序找到了序列 a ,以以下格式打印该行(不带引号):
-
-
-
-
- -”! a1a2…a2n−1a2n ( 1≤ai≤n )”
-
-
-
请注意,这并不计入查询限制。
在此之后,继续进行下一个测试用例,或者退出,如果这是最后一个测试用例。
这个任务中的交互器不是自适应的。换句话说,序列 a 在交互过程中不会改变。
如果您在交互过程中查询的次数超过 3n ,您的程序必须立即终止,并且您将收到错误答案判决。否则,您可能会得到一个武断的结论,因为您的解决方案将继续从已关闭的流中读取数据。
打印每行后,不要忘记输出行尾并刷新输出缓冲区。否则,您将收到超出闲置限制的判决。要冲洗,请使用:
-
c++中的fflush(stdout)或cout.flush();
-
System.out.flush()在Java;
-
Python中的stdout.flush();
-查看其他语言的文档。
要制作一个hack,请使用以下格式:
第一行应该包含测试用例的数量 t ( 1≤t≤3000 )。
每个测试用例的第一行应该包含一个整数 n ( 2≤n≤300 )。
下一行应该包含 2n 整数 a1,a2,…,a2n ( 1≤ai≤n )。从 1 到 n 的每个数字必须恰好出现两次。
所有测试用例 n2 的总和不应超过 105 。
例如,与示例交互对应的hack格式如下所示。
2
2
2 2 1 1
2
1 2 1 2
Example
Input
Copy
2 2 2 0 1 2 0 1 1
Output
Copy
? 2 2 1 ? 2 1 3 ? 3 1 3 4 ! 2 2 1 1 ? 2 1 2 ? 2 1 3 ? 3 1 3 4 ! 1 2 1 2
Note
In the first test case, the hidden sequence is a=[2,2,1,1].
For the query "? 2 2 1", the jury returns 2 because MAD([a2,a1])=MAD([2,2])=2.
For the query "? 2 1 3", the jury returns 0 because MAD([a1,a3])=MAD([2,1])=0.
For the query "? 3 1 3 4", the jury returns 1 because MAD([a1,a3,a4])=MAD([2,1,1])=1.
Note that the example interaction is only for understanding statements and does not guarantee finding a unique sequence a.
思路
注意到3n限制,可以想到为一连串询问,每次寻问1~i中未被标记的,若出解p,则第i位为p,用2n次询问,然后,在以此倒着询问,出解,共4n次。
可以发现,对于二次询问,可以不问已标记过的点,共3n次。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long t,n,a[100005],b[100005],c[100005],lk=0,kl=0;
int main(){
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=2*n;i++){
a[i]=b[i]=0;
}
lk=0;
for(int i=1;i<=2*n;i++){
cout<<"? "<<i-lk<<" ";
for(int j=1;j<=i;j++){
if(a[j]==0){
cout<<j<<" ";
}
}
cout<<endl;
fflush(stdout);
cin>>kl;
fflush(stdout);
if(kl!=0){
lk++;
a[i]=kl;
}
}
lk=0;
for(int i=2*n;i>=1;i--){
if(a[i]==0){
cout<<"? "<<2*n-i+1-lk<<" ";
for(int j=i;j<=2*n;j++){
if(b[j]==0){
cout<<j<<" ";
}
}
cout<<endl;
fflush(stdout);
cin>>kl;
fflush(stdout);
lk++;
b[i]=kl;
}
}
cout<<"! ";
for(int i=1;i<=2*n;i++){
cout<<max(a[i],b[i])<<" ";
}
cout<<endl;
fflush(stdout);
}
return 0;
}

浙公网安备 33010602011771号