思路就是二分出当前最大答案的位置,再将其删除,继续循环下一个最大值,但有几个点TLE了,不知道是不是死循环
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=5010;
inline int read() {
register int x=0,f=1;
register char c=getchar();//getchar()yyds!
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
int a[501];
int T,n;
signed main()
{
//freopen("data.in","r",stdin);
T=read();
for(; T ; T--)
{
memset(a,0,sizeof(a));
n=read();
int cnt=n;//记录当前最大值
for(int i=1;i<=n;i++)
{
int l=1,r=n;
printf("? 1 %d\n",n);fflush(stdout);
int k; k=read();
int x;
while(l!=r)
{
int mid=(l+r)>>1;
printf("? 1 %d\n",mid);fflush(stdout);
x=read();
if(x<k)
{
l=mid+1;
}
else if(x==k)
{
r=mid;
}
}
a[l]=cnt; --cnt;
if(i==n-1)
{
for(int j=1;j<=n;j++)
{
if(!a[j]) a[j]=1;
}
break;
}
else
printf("? 2 %d\n",l);fflush(stdout);
}
printf("! ");
for(int i=1;i<=n;i++) printf("%d ",a[i]);
printf("\n");
}
return 0;
}