Oppure

Loading
27/01/13 23:10
Maury91
Postato originariamente da Saik:

i primi 4 valori combaciano il 5 no : a me esce 999900000

il valore non può essere più grande di k...
nel case #6 il mio entra sicuramente in un loop con la struttura se riuscissi a risolvere questo problema sarebbe velocissimo
aaa
27/01/13 23:18
pierotofy
E per valutarli tutti e 20?
Il mio blog: piero.dev
27/01/13 23:24
Maury91
Postato originariamente da pierotofy:

E per valutarli tutti e 20?


non ci riusciva...
allora son riuscito a risolvere il problema del #6 in pratica il BUG era nella generazione.. io usavo

m[i]=(b*m[i-1]+c)%r

ovvero la formula diretta... questo genera un overflow nel 6 che manda il programma in ciclo...

ho modificato il codice.. ora arriva al 8 poi da errore e ho anche capito perché xD
c'è il caso che non avevo contato :

1000000000 1
12 7 74 12

ovvero k=1 con risultante per forza 0 xD

ora testo il codice nuovo xD
aaa
27/01/13 23:27
Maury91
OK è riuscito a mangiarseli tutti e 20 :

loaded!
Case #1 : 58
loaded!
Case #2 : 29
loaded!
Case #3 : 76
loaded!
Case #4 : 41
loaded!
Case #5 : 90001
loaded!
Case #6 : 21563
loaded!
Case #7 : 573
Case #8 : 0
loaded!
Case #9 : 6
loaded!
Case #10 : 12
loaded!
Case #11 : 38
loaded!
Case #12 : 19906
loaded!
Case #13 : 2
loaded!
Case #14 : 8
loaded!
Case #15 : 30023
loaded!
Case #16 : 42
loaded!
Case #17 : 26
loaded!
Case #18 : 9999
loaded!
Case #19 : 3860
loaded!
Case #20 : 12

Process returned 0 (0x0) execution time : 168.692 s
Press any key to continue.


Edit:
Ho scaricato ora il file input dal sito vediamo come va :D
Ultima modifica effettuata da Maury91 27/01/13 23:29
aaa
27/01/13 23:51
Maury91
Questo è il codice che ho usato, purtroppo nella versione ottimizzata risulta avvolte instabile non son riuscito a capire come risolvere questa rara instabilità...

#include <stdio.h>
#include <stdlib.h>

typedef struct findmin_t {
    int num;
    struct findmin_t* prev;
    struct findmin_t* next;
    struct findmin_t* next_del;
    int exist;
} findmin;

findmin *min,*f_del;

void insert_order(findmin *ins,findmin *start) {
    findmin *s;
    //Inserimento ordinato.. è quello che rallenta il codice,
    //ottimizzando questo il codice può diventare velocissimo...
    if (start!=NULL)
        s=start;
    else
        s=min;
    if (ins->num<=s->num) {
        s->prev=ins;
        ins->next=s;
        min=ins;
    } else {
        while((s->num<ins->num)&&(s->next!=NULL)) {
            s=s->next;
        }
        if (s->num<ins->num) {
            s->next=ins;
            ins->prev=s;
            ins->next=NULL;
        } else {
            ins->prev=s->prev;
            s->prev->next=ins;
            ins->next=s;
            s->prev=ins;
        }
    }
}

long int testcase(long int a,long int b, long int c, long int r, long int n, long int k) {
    long int s[k+1],i,now;
    findmin *exit=NULL,*l_del,*l_min=NULL,*sup,*l_ins,*ff;
    int l;
    //Preveniamo errori
    if (k<2) return 0;
    s[0]=a;
    min = (findmin*)malloc(sizeof(findmin));
    min->num=a;
    min->prev=NULL;
    min->next=NULL;
    min->next_del=NULL;
    f_del=l_ins=min;
    for(i=1;i<k;i++)
    {
        long long int tmp1=b%r;
        long long int tmp2=s[i-1]%r;
        long long int ltmp=tmp1*tmp2;
        ltmp=ltmp%r;
        long long int tmp3=ltmp;
        long long int tmp4=c%r;
        long long int final=(tmp3+tmp4)%r;
        s[i]=final;
        sup=(findmin*)malloc(sizeof(findmin));
        sup->num=s[i];
        sup->exist = 1;
        l_ins->next_del=sup;
        insert_order(sup,NULL);
        l_ins=sup;
    }
    l=k;
    for (i=k;i<n;i++) {
        now=0;
        if (min->num==0) {
            if (l_min==NULL)
                sup=min;
            else {
                //Scelgo il punto di partenza più conveniente
                if (exit->num<l_min->num) {
                    if (l_ins->num<exit->num) {
                        now = l_ins->num;
                        sup = l_ins;
                    }
                    else {
                        now = exit->num;
                        sup = exit;
                    }
                }
                else{
                    if (l_ins->num<l_min->num) {
                        now = l_ins->num;
                        sup = l_ins;
                    }else {
                        now = l_min->num;
                        sup = l_min;
                    }
                }
                //Torno indietro di uno se possibile
                if (sup->prev!=NULL)
                    sup = sup->prev;
            }
            //Cerco quello immediatamente successivo nella lista
            while((sup->next!=NULL)&&(now>=sup->num)) {
                if (now==sup->num)
                    now++;
                else {
                    sup=sup->next;
                }
            }
            //Se sono alla fine della lista e quindi son uscito perché è l'ultimo elemento, incremento now
            if (sup->num==now)
                now++;
            //Mi salvo qual'è l'ultimo trovato
            l_min=sup;
        }
        //Eliminazione
        if (f_del->prev!=NULL) {
            f_del->prev->next = f_del->next;
            f_del->exist = 0;
        } else
            min=f_del->next;
        if (f_del->next!=NULL)
            f_del->next->prev = f_del->prev;
        if (exit!=NULL)
            free(exit);
        //Salvo l'ultimo elemento uscito (molto utile a fini statistici)
        exit=f_del;
        f_del=f_del->next_del;
        //Creo un nuovo elemento
        sup=(findmin*)malloc(sizeof(findmin));
        sup->num=now;
        sup->exist = 1;
        l_ins->next_del=sup;
        //Capita qualche volta che si corrompa il risultato
        //Mettendo come commento da qui fino all'else il risultato sarà sicuramente corretto!
        if (l_min!=NULL) {
            ff=l_min->prev;
            if (!ff->exist)
                ff = min;
            while (!ff->exist) {
                ff = ff->prev;
                if (ff==NULL)
                    ff=min;
            }
            insert_order(sup,ff);
        }
        else
            insert_order(sup,NULL);
        l_ins=sup;
        //Salvataggio nella matrice (ora inutilizzata)
        s[i%(k+1)]=now;
        if (i==k*2) return s[(n-1)%(k+1)];
    }
    return now;
}

int main() {
    FILE *f,*f2;
    int cont,i;
    long int n,k,a,b,c,r;
    f = fopen("input.txt","r");
    f2 = fopen("output.txt","w");
    fscanf(f,"%d",&cont);
    for (i=0;i<cont;i++) {
        fscanf(f,"%d %d",&n,&k);
        fscanf(f,"%d %d %d %d",&a,&b,&c,&r);
        printf("Case #%d : %d\n",i+1,testcase(a,b,c,r,n,k));
    }
    fclose(f);
    fclose(f2);
    return 0;
}
Ultima modifica effettuata da Maury91 28/01/13 14:42
aaa
28/01/13 7:54
panthe
Postato originariamente da pierotofy:

I primi *k* elementi, nel senso che ad ogni indice i devi considerare i k elementi precedenti.

Ad esempio, se k = 5 e n = 10, per i = 8 devi considerare gli elementi 3,4,5,6,7 (5 elementi precedenti, omettendo 0,1,2).


Ciao a tutti,
anche io sto cercando di risolvere questo problema ma non ho molto capito il discorso dei primi k elementi.
Anche io come prima stesura ottengo gli stessi risultati dei k elementi (come in uno dei primi post), è evidente che non ho capito cosa viene richiesto.

Qualcuno ha l'output corretto degli elementi conosciuti del primo esempio?
Ultima modifica effettuata da panthe 28/01/13 7:55
aaa
28/01/13 13:56
Maury91
Usa questo programma per calcolare gli output corretti :
il file di input deve chiamarsi "input.txt" troverai il risultato in "out.txt"
Ultima modifica effettuata da Maury91 28/01/13 13:59
aaa
28/01/13 14:05
panthe
Postato originariamente da Maury91:

Usa questo programma per calcolare gli output corretti :
il file di input deve chiamarsi "input.txt" troverai il risultato in "out.txt"


Ciao Maury,
grazie della risposta, penso però di esserci arrivato, comunque controllo con il tuo per la conferma.
Mi ero fatto trarre in inganno dal testo ed il fatto di trovare il numero 8 nei k calcolati mi creava confusione, da lì in poi ok e sto cercando di capire il discorso dell'ottimizzazione.
Mi sembra che ci sia una serie ripetuta lunga k a partire dal k-esimo elemento quindi l'idea che ho è calcolare in posizione mod k sta l'elemento n-esimo e ricavare quindi solo gli elementi necessari a calcolarlo...
Ti dirò magari posto qui appena fatto.
Grazie
Ciaoooo
aaa