1. 程式人生 > 實用技巧 >Codeforces Round #669 (Div. 2) C. Chocolate Bunny 題解(互動)

Codeforces Round #669 (Div. 2) C. Chocolate Bunny 題解(互動)

題目連結

題目大意

有一個長度為n的全排列,你可以詢問2n次,要你經過這個2n次的詢問後,求出這個全排列

詢問定義為:輸入"? i j"輸出\(p_{i} mod p_{j}\)

題目思路

比賽的時候想了很久都沒思路,一直想的是用O(n)的方法確定出這個全排列n的位置,然後再用O(n)用其他位置的數去模它。結果一直沒寫出來。

這個題目的思路其實就是兩個數互模,那麼大的的那個模數必然是這兩個數中的小的那個數

然後題目就變得簡單起來,每2次查詢就能確定一個值,然後再用另外一個不確定的值去和其他數互模,顯然最後剩下來的就是那個最大的數n

程式碼

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const double eps=1e-10;
int n,a[maxn];
signed main(){
    scanf("%d",&n);
    int st=1;
    for(int i=2,x,y;i<=n;i++){
        printf("? %d %d\n",st,i);
        fflush(stdout);
        scanf("%d",&x);
        printf("? %d %d\n",i,st);
        fflush(stdout);
        scanf("%d",&y);
        if(x>y){//a[st]<a[i]
           a[st]=x;
           st=i;
        }else{
            a[i]=y;
        }
    }
    a[st]=n;
    printf("! ");
    for(int i=1;i<=n;i++){
        printf("%d%c",a[i],i==n?'\n':' ');
    }
    fflush(stdout);
    return 0;
}