题目传送门
题目大意
求一个长度为n的数组
每次可以输入两个值i和j询问,将会得到一个为
p
i
m
o
d
p
j
p_i\ mod\ p_j
pi mod pj返回值,最多可以进行2*n次询问
思路
注意到询问的最高次数为2*n次,所以每位最多在两次询问中确定
再注意到
p
i
m
o
d
p
j
p_i\ mod\ p_j
pi mod pj,联想到小的值mod大的值为本身,所以可以通过不同方法询问两个值(即询问i j和询问j i),得到较小的那个值,通过这种方法将数组走一遍,每次tmp为当前未知的大值,小值记录进数组,最后大值即为最大的n,将其放入数组即可
AC Code
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
#define endl '\n'
#define INF 0x3f3f3f3f
#define int long long
// #define TDS_ACM_LOCAL
const int N=2e5 +9;
int n, a[N];
void solve(){
cin>>n;
int tmp=1;
for(int i=2; i<=n; i++){
int q, p;
cout<<"? "<<tmp<<" "<<i<<endl;
cin>>q;
cout<<"? "<<i<<" "<<tmp<<endl;
cin>>p;
if(q < p) a[i]=p;
else a[tmp]=q, tmp=i;
}
a[tmp]=n;
cout<<"!";
for(int i=1; i<=n; i++) cout<<" "<<a[i];
cout<<endl;
return ;
}
signed main(){
solve();
return 0;
}