Findperm Execution killed

Salve,
oggi nel secondo round delle OIS è uscito il problema findperm. Il problema era interattivo, e dato un intero N (1 \leq N \leq 1000), che rappresentava la lunghezza di un vettore P contenente tutti i numeri da 1 a N, il nostro obbiettivo era indovinare una permutazione di P nascosta, potendo fare Q richieste al problema del tipo “? i j(1\leq i,j, \leq N) e per ognuna di queste Q domande il problema doveva rispondere con la posizione del bit più significativo risultante dall’operazione P_i \& P_j ovvero il bitwise and tra i due valori, dove ricordo P essere la permutazione da indovinare, se i due valori non avessero bit in comune, quindi P_i\&P_j = 0 allora avrebbe restituito -1.

quindi facendo un esempio, con N = 5 e P = \{4, 3, 2, 5, 1\} se faccio la richiesta “? 2 4” allora il problema mi restituirà P_2 \& P_4 = 3\&5 = 011\&101 = 001 \to 0 essendo il bit più significativo in posizione 0.

Il problema valutava il mio algoritmo in base alle domande inviate, nel caso in cui Q \geq 30000 avrei ricevuto 0 punti e così via con la suddivisione in varie subtask che non mi serve nominare.

Dato tutto questo, io ho avuto vari problemi con il mio algoritmo ottenendo in ogni testcase l’errore “Execution Killed” però stando nei limiti di memoria imposti dal problema. Ho pensato quindi che l’unica cosa possibile è o sbagliare o far sbagliare qualche accesso a qualche vettore o cose del genere. Dopo vari tentativi di fixare, creo un altro file da capo dove mando una richiesta a caso e stampo una permutazione a caso, per riuscire ad ottenere almeno “Output isn’t correct”.

#include <bits/stdc++.h>
using namespace std;

int main(){
    int N; cin >> N;

    cout << "? " << 1 << " " << 1 << endl;
    cout.flush();

    int x; cin >> x;

    cout << "! ";

    for(int i = 1; i <= N; ++i){
        cout << i << " ";
    }

    cout << endl;
    cout.flush();

    return 0;
}

Questa tattica funziona, e infatti ottengo ad ogni testcase “Output isn’t correct” e non più “Execution killed”. Allora ho provato a confrontare i due codici ma qualcosa non andava, non sembrava fare niente di tanto diverso il codice “serio” rispetto a quello di “debug”, tranne che quello “serio” mandava più domande di quello “debug”.

Quindi modifico quello “debug” facendo la stessa domanda 25000 volte, in modo di rientrare di molto nel limite imposto dal problema ma comunque sparare più domande. (anche se superato mi avrebbe dovuto dare TLE, o almeno così diceva il testo)

#include <bits/stdc++.h>
using namespace std;

int main(){
    int N; cin >> N;

    for(int i = 0; i < 25000; ++i){

        cout << "? " << 1 << " " << 1 << endl;
        cout.flush();

        int x; cin >> x;
    }

    cout << "! ";

    for(int i = 1; i <= N; ++i){
        cout << i << " ";
    }

    cout << endl;
    cout.flush();

    return 0;
}

Disastro, tutti i testcase “Execution killed” tranne l’esempio, ho perso tipo 40 min di gara solamente per sto problema, pensando di poterlo risolvere ma niente da fare, ed è un gran peccato.

Sapete dirmi dov è l’errore? Sto rosicando tantissimo anche perchè non è nemmeno una tecnica di programmazione su cui allenarsi o cose del genere, quindi se avrei dovuto fare cose tipo dare una specie di pausa per non sovraccaricare l’input, mi darebbe fastidio perchè è una cosa che andrebbe messa nel testo e che non sono tenuto a sapere.

Queste sono le mie considerazioni a caldo, quindi non voglio nemmeno sembrare arrogante, è probabilissimo che abbia letto male il testo o magari mi è scappato qualche errore che non ho visto. Se non fosse così vi prego di farmi capire cosa sbaglio almeno evito di perseverare la prossima volta. Grazie in anticipo per le eventuali risposte.

2 Mi Piace

ho provato a sottoporre questo codice e ha me da solo output non corretto, non “Execution killed”, sicuro che il codice fosse esattamente questo?
A me aveva dato lo stesso errore (“Execution killed”) perché avevo formulato male l’output (avevo dimenticato il ‘?’), corretto quello funzionava.

1 Mi Piace

allora, all’inizio anche io, (ho usato il cpp fornito dal testo, e sono stato mezz’ora prima di capire che mancava il punto interrogativo) ma comunque poi ho risolto, ho controllato più volte, peró sinceramente non ti so dire, sai se esiste un modo per ottenere in qualche modo i file che ho sottomesso? E poi c’è un modo per sottomettere ancora il problema o devo aspettare che esca su training?

per ottenere i file che hai sottomesso non lo so, però puoi riprovare i problemi facendo l’accesso al mirror contest

1 Mi Piace

ok ho provato a mandare il file serio (che doveva fare qualche punto), riuscite a dirmi che sbaglio?

#include <bits/stdc++.h>
using namespace std;

int main(){
    	int N; cin >> N;
	vector<vector<bool>> v(N+1, vector<bool>(11, false));
   

    	for(int i = 1; i < N; ++i){
		for(int j = i + 1; j <= N; ++j){

	        	cout << "? " << i << " " << j << endl;
        		cout.flush();

	        	int x; cin >> x;

			if(x == -1) continue;

			v[i][x]	= true;
			v[j][x] = true;		
		}
    	}

    	cout << "! ";

    	for(int i = 1; i <= N; ++i){
        	int res = 0, coef = 1;

		for(int j = 0; j < 10; ++j){
			res += coef * v[i][j];
			coef *= 2;
		}

		if(res == 0) res = N;
		
		cout << res << " ";
    	}

    	cout << endl;
    	cout.flush();

    	return 0;
}


l’esempio che funziona, e tutti gli altri “Execution killed”. perchè :sob:?

il problema è che la tua soluzione è troppo lenta, o meglio fa troppe domande (superando sempre il limite delle 30000). Nel testo c’è scritto che superando questo limite la risposta che otterrai sarà -100, perciò a un certo punto questo pezzo di codice:

assegnerà -100 a x che quindi non sarà un indice valido per accedere al vettore, causando “Execution killed”.

mi ero saltato sto pezzo, più che altro mi ha destabilizzato quando ho provato il codice fino a 25k ma probabilmente avró fatto qualche altro errore passato inosservato. Vabbe unlucky, grazie mille per l’aiuto!

1 Mi Piace