Codeforces Ronda # 720 (Div. 2)

Codeforces Ronda # 720 (Div. 2)

Título:
inserte la descripción de la imagen aquí
La idea principal del título:
Hay una permutación oculta p de longitud n, que consiste en números enteros de 1 a n. Debe realizar este arreglo como máximo 3*n/2+30 consultas.

Idea:
puedes usar la siguiente consulta:
t=1 : max(min(x,pi),min(x+1,pj)); t=
2 : min(max(x,pi),max(x+1 ,pj) ));

Se puede usar un máximo de 3*n/2+30 consultas para encontrar la permutación p, por lo que se pueden usar n/2 veces para encontrar la posición del valor máximo n, y luego n veces para encontrar el valor de cada posición.

Primero pase t=1: max(min(x,pi),min(x+1,pj)); encuentre la posición del máximo n en el arreglo p, sea x == n-1, luego ans=max( min (n-1,pi),min(n,pj));
si ans=n, significa que pj debe ser n; si ans=n-1, significa que pi es igual a n-1 o igual a n, y pi Cambia la posición de pj y continúa consultando, ans=max(min(n-1,pj),min(n,pi)), si ans=n, significa que pi es igual a n;

Después de encontrar el subíndice del valor máximo n, pase t=2: min(max(x,pi),max(x+1,pj)); sea x=1, pj es el subíndice del valor máximo n, en esta vez ans =min(max(1,pi),max(2,ppos))=min(pi,n)=pi, entonces puedes obtener el número de cada posición.

código:

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int a[N];
int n;
int ask(int t,int i,int j,int x) {
    cout << "? " << t << " " << i << " " <<  j << " " << x << endl;
    // cout.flush();
    int res;
    cin >> res;
    return res;
}
void printResult() {
    cout << "! ";
    for(int i=1;i<=n;i++) {
        cout << a[i] << " ";
    }
    cout << endl;
    // cout.flush();
}
int main() {
    int t;
    cin >> t;
    while(t--) {
        cin >> n;
        int pos=n;//寻找最大值下标
        for(int i=1;i<n;i+=2) {
            int ans=ask(1,i,i+1,n-1);
            if(ans==n) {
                pos=i+1;
                break;
            }
            else if(ans==n-1) {
                ans=ask(1,i+1,i,n-1);
                if(ans==n) {
                    pos=i;
                    break;
                }
            }
        }
        a[pos]=n;
        for(int i=1;i<=n;i++) {
            if(i==pos) continue;
            a[i]=ask(2,i,pos,1); 
        }
        printResult();
    }
    return 0;

}

Para problemas interactivos, puede usar cout.flush() para vaciar el búfer después de cada salida, o puede usar directamente cout<<endl, porque endl puede vaciar el búfer automáticamente.

Supongo que te gusta

Origin blog.csdn.net/weixin_45937795/article/details/116564062
Recomendado
Clasificación