Submission #1353755

#TimeUsernameProblemLanguageResultExecution timeMemory
1353755AvianshTower (BOI25_tow)C++20
13 / 100
6023 ms327680 KiB
#include <bits/stdc++.h>

using namespace std;

map<array<int,3>,set<array<int,2>>>mem;

set<array<int,2>>query(int x, int y, int z){
    vector<int>arr(3);
    arr[0]=x;
    arr[1]=y;
    arr[2]=z;
    sort(arr.begin(),arr.end());
    x=arr[0];
    y=arr[1];
    z=arr[2];
    if(mem.find({x,y,z})!=mem.end()){
        return mem[{x,y,z}];
    }
    cout << "? " << x << " " << y << " " << z << endl;
    int r;
    cin >> r;
    set<array<int,2>>ans;
    for(int i = 0;i<r;i++){
        int a,b;
        cin >> a;
        cin >> b;
        ans.insert({a,b});
    }
    return mem[{x,y,z}]=ans;
}

vector<int>bin(vector<int>arr){
    int n = arr.size();
    while(n==0){
        continue;
    }
    if(n<=2){
        return arr;
    }
    vector<int>left,right;
    set<int>parted;
    int x = arr[rand()%n];
    int y = arr[rand()%n];
    while(y==x){
        y = arr[rand()%n];
    }
    parted.insert(x);
    parted.insert(y);
    left.push_back(x);
    right.push_back(y);
    while(parted.size()!=n){
        int z = arr[rand()%n];
        while(parted.find(z)!=parted.end()){
            z = arr[rand()%n];
        }
        set<array<int,2>>q = query(x,y,z);
        if(q.find({min(x,z),max(x,z)})!=q.end()){
            ///this one exists so put in left
            parted.insert(z);
            left.push_back(z);
        }
        else if(q.find({min(y,z),max(y,z)})!=q.end()){
            ///it exists in right
            parted.insert(z);
            right.push_back(z);
        }
        else{
            ///huh must restart
            parted.clear();
            left.clear();
            right.clear();
            ///lets take x,z as it bigger
            y=z;
            parted.insert(x);
            parted.insert(y);
            left.push_back(x);
            right.push_back(y);
        }
    }
    ///partition successful
    vector<int>lf = bin(left);
    vector<int>rg = bin(right);
    if(lf.size()<rg.size()){
        swap(lf,rg);
    }
    set<array<int,2>>q=query(lf.back(),lf.front(),rg.front());
    if(q.find({min(lf.front(),rg.front()),max(lf.front(),rg.front())})!=q.end()){
        reverse(lf.begin(),lf.end());
    }
    if(rg.size()!=1){
        q=query(rg.back(),rg.front(),lf.front());
        if(q.find({min(lf.back(),rg.back()),max(lf.back(),rg.back())})!=q.end()){
            reverse(rg.begin(),rg.end());
        }
    }
    vector<int>ans;
    for(int i : lf){
        ans.push_back(i);
    }
    for(int i : rg){
        ans.push_back(i);
    }
    return ans;
}

void dfs(int st, vector<int>g[], bool vis[]){
    vis[st]=1;
    cout << st << " ";
    for(int i : g[st]){
        if(vis[i])
            continue;
        dfs(i,g,vis);
    }
}

void solve(){
    mem.clear();
    int n;
    cin >> n;
    vector<int>g[n];
    for(int i = 0;i<n;i++){
        for(int j = i+1;j<n;j++){
            bool wor=1;
            for(int k = 0;k<n;k++){
                if(i==j||j==k||i==k)
                    continue;
                set<array<int,2>>q = query(i,j,k);
                if(q.find({i,j})==q.end()){
                    wor=0;
                    break;
                }
            }
            if(wor){
                g[i].push_back(j);
                g[j].push_back(i);
            }
        }
    }
    for(int i = 0;i<n;i++){
        assert(g[i].size()==2);
    }
    cout << "! ";
    bool vis[n];
    fill(vis,vis+n,0);
    dfs(0,g,vis);
    cout << endl;
    return;
    vector<int>arr(n);
    iota(arr.begin(),arr.end(),0);
    vector<int>ans = bin(arr);
    cout << "! ";
    for(int i : ans){
        cout << i << " ";
    }
    cout << endl;
}

signed main(){
    int t,k;
    cin >> t >> k;
    while(t--){
        solve();
    }
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...