理清思路一步步实现即可
#include <bits/stdc++.h>
const int MAX_N = 10;
#define ll long long
using namespace std;
/*
codeforces 883 div3 F Rudolph and Mimic
交互题
分类讨论
1、第一轮开始 记录每种物品个数 ,不做删减
2、第二轮开始 若出现了物品个数变化
a、 某个物品个数减小某个类型物品数量增加(未引入不在房间内的物品)
那么该轮将除了物品数量增加的类型保留 其余全部删除
在至多俩轮的过程中会得到出现物品数量变化的物品类型即所求
b、 引入了不在房间的物品即指向它即可
*/
void solve(){
vector<int>a(MAX_N,0);
int n,x;
cin>>n;
for(int i=0;i<n;i++) {
cin>>x;
a[x]++;
}
//物品类型范围 1≤ai ≤9
cout<<"- 0"<<endl;//第一轮不进行删除操作静观其变
int total = n;//剩余个数
while(1){
vector<int>b(MAX_N,0);
vector<int>id[MAX_N];
for(int i=1;i<=total;i++){
cin>>x;
b[x]++;
id[x].push_back(i);//存放此轮位置
}
bool flag=false;
int i;
for(i=1;i<=9;i++){
if(a[i] < b[i]){
flag=true;
break;
}
}
if(!flag){
//该轮没有变化则仍然不进行操作
//do nothing
// fill(b.begin(),b.end(),0);
cout<<"- 0"<<endl;
}else{
//发现了 i 类型的物品数量增加
//将除此之外的所有物品删除
vector<int>del;
for(int j=1;j<=9;j++){
if(j == i || a[j]==0)continue;
del.push_back(j);
}
//只保留 i类型的物品其余全删除
set<int>del_id;
for(int j=0;j<del.size();j++){
for(int k=0;k< id[del[j]].size() ;k++ ){
del_id.insert(id[del[j]][k]);
}
}
total -= del_id.size();//更新
if(total == 1){
//只剩下一个的时候直接指向该位置
//指向 i 类型物品
cout<<"! "<<id[i][0]<<endl;
return;
}
cout<<"- "<<del_id.size();
//顺便将a数组更新成删除后的
vector<int>A(MAX_N,0);
A[i]=total;
a=A;
for(set<int>::iterator it=del_id.begin();it!=del_id.end();it++){
cout<<" "<<*it;
}
cout<<endl;
}
}
}
int main(){
/*
交互题避免使用
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
*/
int t=1;
cin>>t;
while(t--){
solve();
}
return 0;
}