Selezioni territoriali 2017

è permesso parlarne? credo di sì visto che i problemi adesso sono praticamente pubblici ma non si sa mai

Problema 1: lwf
Dato un numero in input (N < 10^6 mi pare), il problema consisteva nel tradurlo in una serie di bit, dove ogni bit indica un numero di fibonacci, se il bit è a uno il numero va considerato, altrimenti no.
La somma dei numeri considerati deve essere equivalente al numero in input, quindi per esempio, se in input si ha 19 la sequenza di bit:
0 1 0 0 1 0 1
1 1 2 3 5 8 13
indica che bisogna sommare 13 + 5 + 1 = 19.

Questo era molto semplice, la mia soluzione costruiva la serie di fibonacci fino al numero direttamente più piccolo di quello un input, poi iteravo la serie costruita al contrario, sottraendo i numeri a quello in input qualora fossero minori e mettendo il relativo bit a 1, altrimenti a 0, finchè il risultato della sottrazione non diventava 0.


Problema 2: scommessa (scommesse?)
In input si aveva una sequenza di N numeri (N era sempre un numero dispari < 100 se non sbaglio). I numeri andavano da a N - 1 in ordine casuale.
Era possibile a ogni iterazione eliminare una coppia qualsiasi di numeri consecutivi qualora la loro somma fosse un numero dispari, continuando così finchè non era più possibile eliminarne.
In output bisognava scrivere quanti erano e quali erano i numeri che potevano rimanere sul tavolo dopo una certa sequenza di mosse.
Casi di esempio:
3
1 2 0
Output:
1
0

11
1 0 2 6 4 5 3 9 8 10 7
Output:
2
2 8

Al momento non mi viene in mente altra soluzione che una brute force ricorsiva, ma dovrebbe essere comunque sufficiente per le territoriali, forse si può anche risolvere in DP.


Problema 3: tecla
In input veniva dato un grafo con N nodi ed M archi (1 <= N,M <= 30) non pesati.
La storiella diceva che al nodo 0 c’erano un ragno ed un’ ape, ma il ragno era in stato di “BLEAH (diciamo rappresentato con 0)” e quindi non aveva voglia di mangiare l’ape.
Spostarsi su un arco cambiava il ragno da uno stato di “BLEAH” a “SLURP” (rappresentato con 1) ed il problema consisteva nel trovare un percorso che partiva dal nodo 0 e ci riportava lì in stato di “SLURP” (quindi un ciclo di lunghezza dispari) e poi scrivere in output il numero di spostamenti e gli archi attraversati, uno per riga.
Casi di esempio:
Il primo era un triangolo, l’altro era un po’ più complesso e non ho voglia di scriverlo :sweat_smile:.

Con solo 30 archi e nodi una brute force poteva bastare anche qui, anche se avevo pensato a una soluzione basata sulla dfs implementata con stack.


Spero di essermi ricordato tutto.

1 Mi Piace

suppongo di si.
Secondo voi quale sarà il cut off medio di quest’anno?

Boh non so, i task mi sembravano abbastanza semplici quindi credo che sarà necessario fare tipo 48/50 come al solito.
Io sicuramente non sono passato, sono arrivato alla gara che stavo fuso e sono riuscito a risolvere solo il primo, ho provato a fare il secondo e debuggarlo ma leggevo fischi per fiaschi dal terminale e forse non ho neanche trascritto bene i casi di esempio nei file.
Adesso edito il post principale e aggiungo un riassunto dei testi dei problemi per discuterne una soluzione

Anche io non dovrei averle passate.

In ogni caso penso siano state più difficili dello scorso anno (con cut off sui 44 circa)

Il primo l’ho risolto generando una sequenza di Fibonacci fino ad arrivare ad un numero maggiore di quello di input. Poi basta sommare i più grandi numeri minori di quello di input fino a raggiungere un numero equivalente

Per il secondo ho passato 40min a debuggare… considerando una lista di interi, per vedere se un numero n può rimanere, ho fatto come se non ci fosse (tenendo conto del fatto che non posso togliere due numeri a sinistra e destra di n) ed ho eliminato in ordine le coppie di somma dispari. Alla fine può rimanere se non si può fare nessun altra mossa TENENDO conto dello stesso. In ogni caso ha poco senso e senza una certezza, oltre che ad essere brutto.

Il terzo non ho avuto tempo di farlo bene quindi ho fatto un bruteforce ricorsivo di prepotenza, tenendo conto del flag e del fatto che non posso ripassarci se ci sono già passato due volte ( con flag true e false)
Pensandoci si poteva fare una bfs…
Così fa schifo

Te?

Forse erano più difficili, quello dello scorso anno in particolare erano parecchio facili.
Il primo l’ho fatto praticamente come te, il secondo avevo provato una brute force ma non credo di averla implementata bene, il terzo non l’ho consegnato proprio ma stavo provando una variante della dfs, tu come pensavi di usare una bfs invece?

Pensavo di invertire il segno del nodo ad ogni passaggio (da 0 a 1 o viceversa, magari tenendo tutto inizialmente ad infinito) e usare la bfs per vedere quando, con percorsi diversi, ottengo un valore diverso dall’altro.

In questo modo basta che unisco i due percorsi (li posso anche ricalcolare volendo, sapendo che devo partire da 0 per arrivare al nodo trovato, togliendo l’ultimo ramo di collegamento dell’altro percorso)

1 Mi Piace

Il primo l’abbiamo fatto allo stesso modo, il secondo ho scritto una funzione ricorsiva che provava le varie combinazioni, fino a N=20 circa andava abbastanza bene, ma il testcase con N=91 andava troppo lento.
Il terzo l’ho fatto con una dfs, ritornando il percorso di lunghezza dispari (visto che ad ogni passo si inverte lo stato del ragno) tenendo conto che può passare più volte sui nodi ma non sugli archi.

Per il secondo (scommesse) potrebbe interessare questo trucchetto:
affinché una carta possa rimanere fino alla fine è sufficiente pensare al numero di carte pari e dispari alla sua destra e alla sua sinistra, senza nessuna ricorsiva…

spoiler

le carte pari di destra devono essere di numero uguale a quelle dispari di destra, stessa cosa a sinistra

1 Mi Piace

Ciao, io ho implementato il primo un po’ come voi e poi a casa dovrei avere fatto una dimostrazione accettabile del fatto che la soluzione fosse proprio quella, mi sono poi fiondato sul grafo (mio argomento preferito) e l’ho risolto con una BFS. In poche parole esploravo il grafo segnando mi i nodi con 0 e 1. Controllavo poi ogni volta che se stavo guardavo un nodo già visitato il suo stato e in caso era lo stesso del nodo attuale allora il percorso che mi ha portato all’attuale unito a quello del nodo che poteva avere due stati era la soluzione. Con un semplice backtracking trovavo i percorsi. Andava bene anche la DFS, ma sul momento non mi veniva in mente il criterio secondo il quale esplorare un nodo oppure no.
Per scommesse invece la soluzione non era (a parere mio e di miei amici) ricorsiva o in dp bensí greedy e piú o meno come ha scritto @rego. Sfortunatamente in gara non mi é venuto in mente è un po’ mi spiace dato che non era poi cosí difficile

1 Mi Piace

Le carte pari e dispari da un lato devono essere per forza in egual numero? In teoria se il mio numero è pari e quelle di destra sono più pari che dispari (o viceversa e lo stesso a sinistra) dovrebbe essere comunque una soluzione accettabile

Per il grafo è corretto fare una BFS per trovare le distanze di ogni nodo da 0, e successivamente prendere 2 nodi A e B, collegati tra loro e avente stessa parità e stampare come percorso 0-…-A-B-…-0? (in questo modo la lunghezza sarebbe dist[A]+dist[B]+1, quindi dispari)

Il fatto è che non importa la posizione delle carte pari e dispari, salvo che siccome devono sempre essere eliminate per coppie adiacenti bisogna distinguere fra quelle a dx e sx della carta che si sta studiando. A presciendere dalla loro posizione, ciò che conta affinché siano tutte eliminabili è che il numero di carte pari e dispari sia lo stesso. Questo perché se per essere eliminata una coppia deve avere somma dispari, è necessario che essa sia composta di una carta pari e una dispari (infatti, pari+pari=pari e dispari+dispari=dispari). Abbiamo quindi N coppie di carte pari/dispari, a cui corrispondo n carte pari e n carte dispari, cioè lo stesso numero.
Se invece abbiamo come dici tu uno squilibrio fra carte pari e dispari, non sarà possibile eliminare tutte le carte a dx/sx della carta scelta, e dovremmo appunto utilizzare tale carta per andare avanti nel gioco.

Buon pomeriggio a tutti,
per curiosità qualcuno sa quando sul portale di allenamento compariranno i problemi della fase territoriale?

Ma è davvero necessario eliminarle tutte? Il testo, a meno che io mi ricordi male, diceva che il gioco finiva quando non è più possibile fare mosse, non quando rimane una sola carta. Quindi, se rimangono anche 3 carte ma sono tutte pari, il gioco termina. Di conseguenza, se ho uno squilibrio fra pari e dispari a favore dello stato della carta in esame, potrei rimanere con carte che avanzano ma non potrebbero comunque essere utilizzate per eliminarla.

Sicuro che tu possa terminare con 3 carte pari? :stuck_out_tongue:

1 Mi Piace

Hai ragione, non avevo tenuto in considerazione il fatto di avere le carte numerate in ordine fino a N-1, e non casualmente. Grazie per il chiarimento

Riguardo ai test case, nella mia sede pare che nessuno sia riuscito ad accedervi ed il professore non era di aiuto…

Arrivati ad un certo punto non ho capito più nulla. Il primo l’ho risolto con un metodo diciamo greedy… Essendo i numeri Fibonacci numeri ovviamente ordinati dopo essermi creato un vettore con tutti i numeri di Fibonacci minori o uguali a N, ho cercato con una ricerca binaria quello strettamente minore, facevo una sottrazione e continuavo allo stesso modo fino a che la sottrazione non da zero. Il fatto è che funziona :joy:. Il secondo sinceramente ancora non l’ho capito, sono andato in panico, alla fine ho optato per un metodo a forza bruta ho creato 2 vettori inserendo all’interno rispettivamente i numeri rimanenti iniziando ad eliminare dall’inizio e i numeri iniziando ad eliminare dalla fine. Se alla fine erano uguali ne stampavo uno solo altrimenti merge. Il terzo lo avevo praticamente​ finito, usando i flag di fame o non fame con una specie di dijkstra appena arrivavo al nodo 0 con il flag a true usciva, dovevo finire di stampare tutti i nodi attraversati in sequenza ma è scaduto il tempo. Ahimè ci riproverò l’anno prossimo…

È possibile dimostrare che questo algoritmo è sempre corretto :slight_smile:

È una domanda?? gli algoritmi greedy sono di difficile dimostrazione… ho provato fino ad un milione e il risultato è giusto.

No è effettivamente un teorema dimostrato, puoi trovare informazioni qui e qui.[quote=“bigsheep, post:17, topic:4607”]
Ahimè ci riproverò l’anno prossimo…
[/quote]

Beato te che puoi riprovarci :joy:, questa per me era la prima e ultima occasione e ho un po’ l’amaro in bocca perchè credo che in condizioni ottimali avrei potuto far bene, ma per citare Junior nel doppiaggio italiano di dbz: “con i se non si vince”, quindi tanto vale mettersi l’anima in pace.