infoarena

infoarena - concursuri, probleme, evaluator, articole => Arhiva de probleme => Subiect creat de: Adrian Diaconu din August 10, 2007, 16:00:00



Titlul: 504 Euclid
Scris de: Adrian Diaconu din August 10, 2007, 16:00:00
Aici puteţi discuta despre problema Euclid (http://infoarena.ro/problema/euclid).


Titlul: Răspuns: 504 Euclid
Scris de: Bogdan-Cristian Tataroiu din August 10, 2007, 19:17:44
Nu ar fi mai bine daca ar fi coborata limita de timp in arhiva? Deja sunt destule surse care intra in 4.5 secunde lejer si nu are rost sa ramai cu o problema care tine 2 minute sa se evalueze.


Titlul: Răspuns: 504 Euclid
Scris de: Sima Cotizo din August 10, 2007, 21:14:59
Uite de exemplu daca golesti matricea dupa fiecare test cu memset iti ia 11 secunde... fara max 9 secunde... pe rezolvarea mea... bine, nu iau tle, ci WA, nu stiu de ce... Sunt cazuri speciale ?  :sad:

LE: sorry pt edit, erau 9s...  :oops: nu stiu ce vazusem


Titlul: Răspuns: 504 Euclid
Scris de: Adrian Diaconu din August 10, 2007, 21:32:35
Am pus limita 4s si am reevaluat in arhiva.


Titlul: Răspuns: 504 Euclid
Scris de: Sima Cotizo din August 11, 2007, 10:52:29
Rezolvarea mea are complexitate O( N*M * log N * log M ) si ... nu incape... limita de 4s e pusa ca sa abordam rezolvarea eleganta? .. ca as vrea sa stiu daca era buna si rez mea in concurs, sau macar ce am gresit ...  :)


Titlul: Răspuns: 504 Euclid
Scris de: Filip Cristian Buruiana din August 11, 2007, 11:00:57
Pai rezolvarea mai eleganta mi se pare si mai comod de implementat. Scrie in articol ca ambele obtineau punctaj maxim din ce am vazut. Testele sunt corecte.


Titlul: Răspuns: 504 Euclid
Scris de: Sima Cotizo din August 11, 2007, 11:26:02
Eu o aveam deja implementata... ma rog, tinand cont ca intra in concurs pe ultimele teste cu OK, cred ca ar fi luat 100 cu 11.5 s limita... o sa abordez si metoda eleganta atunci :)  :thumbup:


Titlul: Răspuns: 504 Euclid
Scris de: Farcasanu Alexandru Ciprian din Iulie 30, 2008, 11:48:07
Cod:
"3904ms	50952kb	Time limit exceeded." 
Ce naiba?

E:Pt prima varianta de rezolvare din solutii:
Cod:
 Pentru aceasta, mai intai sa luam di = [log h] si dj = [log w]. Numarul cautat este gcd(V[di][dj][i][j], V[di][dj][i][j + w - dj], V[di][dj][i + h - di][dj], V[di][dj][i + h - di][j + w - dj]) 
Nu este cumva corect asa:
Cod:
  gcd(V[di][dj][i][j], V[di][dj][i][j + w - 2^dj], V[di][dj][i + h - 2^di][dj], V[di][dj][i + h - 2^di][j + w - 2^dj])
Motivul pt care cred eu ca trebuie pus 2^dx(x=i sau j)  este deoarece noi ne dorim 4  dreptunghiuri de laturi 2^di si 2^dj care suprapunandu-se sa formeze dreptunghiul cu colturile (i,j),(i+h-1)(j+w-1).


Cod:
 Putem apoi vedea in O(1) care este gcd-ul elementelor din dreptunghiul cu colturile in (i, j), (i + w - 1, j + h - 1) 
Nu trebuia
Cod:
 cu colturile in (i,j) , (i+h-1,j+w-1) 
?

LE: chiar nu raspunde nimeni nimeni?


Titlul: Răspuns: 504 Euclid
Scris de: Florian Marcu din Iunie 09, 2009, 17:07:00
Ai dreptate. Am modificat articolul cu solutii (http://infoarena.ro/summer-challenge-2007/solutii/runda-2) [ la ambele solutii erau greseli ]. Sper ca nu am gresit nimic.  :)


Titlul: Răspuns: 504 Euclid
Scris de: George Popoiu din Ianuarie 26, 2012, 18:15:24
Cred ca trebuie marita limita de timp. Iau 60p cu O(N * M * logN * logM) si am retrimis o sursa care lua 100p si ia tot 60p.

Am updatat http://infoarena.ro/calibrare-limite-de-timp


Titlul: Răspuns: 504 Euclid
Scris de: Mircea Dima din Ianuarie 26, 2012, 20:39:31
Cred ca trebuie marita limita de timp. Iau 60p cu O(N * M * logN * logM) si am retrimis o sursa care lua 100p si ia tot 60p.

Am updatat http://infoarena.ro/calibrare-limite-de-timp

Din cate stiu, asta nu e solutia optima... deci ar fi ok sa iei 60.


Titlul: Răspuns: 504 Euclid
Scris de: George Popoiu din Ianuarie 26, 2012, 21:10:16
In articolul cu solutii se spune ca solutia O(N * M * logN * logM) ar trebui sa primeasca 100p. Chiar si asa, sursa care lua 100p e in O(N * M * logN) deci solutia optima. Si ia tot 60p.


Titlul: Răspuns: 504 Euclid
Scris de: Paul-Dan Baltescu din Ianuarie 27, 2012, 00:09:02
Fixed.


Titlul: Răspuns: 504 Euclid
Scris de: FMI Ciprian Olariu din Ianuarie 03, 2013, 11:41:18
Nu cumva ar trebui marita putin limita de timp? :)
Cu solutia in O((logN+logM)*N*M) iau 60pct cu TLE,cel mai mare timp pe testele 1-6 fiind de 276ms (http://infoarena.ro/job_detail/847073 (http://infoarena.ro/job_detail/847073)) sau de 208ms daca fac Euclid cu scaderi repetate in loc de modulo (http://infoarena.ro/job_detail/847072 (http://infoarena.ro/job_detail/847072)) :-s


Titlul: Răspuns: 504 Euclid
Scris de: Simoiu Robert din Ianuarie 03, 2013, 12:09:52
Chiar trebuie marita, si eu cu sursa veche iau tot 60.


Titlul: Răspuns: 504 Euclid
Scris de: FMI Ciprian Olariu din Ianuarie 06, 2013, 22:14:45
Deci se ocupa cineva de limita de timp? :-'


Titlul: Răspuns: 504 Euclid
Scris de: Daniel Constantin Anghel din Ianuarie 10, 2013, 20:42:18
vad ca nu modifica nimeni limita de timp.

pentru 100 de puncte sunt necesare si suficiente :
solutia in o(t*n^2*logn);
gcd cu scaderi repetate (ideea lui scipianus);
parsare a intregului fisier de intrare;
grija sa nu spargi cache-ul.


Titlul: Răspuns: 504 Euclid
Scris de: Dumitran Adrian Marius din Ianuarie 31, 2013, 18:50:06
Am marit limita!


Titlul: Răspuns: 504 Euclid
Scris de: Lup Vasile din Octombrie 10, 2014, 17:56:03
De ce merge mai gcd rapid prin scaderi? ???


Titlul: Răspuns: 504 Euclid
Scris de: Bogdan Pop din Februarie 12, 2015, 16:08:58
Teste de calitate!


Titlul: Răspuns: 504 Euclid
Scris de: mihai craciun din Ianuarie 08, 2017, 00:08:58
Am urmarit solutia oficiala si tot iau zero puncte. Am incercat pe cateva teste si totul merge ok. Primesc 3 Incorect si 7 TLE.
#include <stdio.h>

#define r fscanf
#define pr fprintf
#define LOGMAX 20
#define NMmax 600
inline int Max(int a, int b)  {
    if(a > b)
        return a;
    return b;
}

int d[LOGMAX][LOGMAX][NMmax][NMmax], a[NMmax][NMmax];

FILE *f, *g;

int T, m, n, h, w;

inline int log(int x)  {
    int ret = 0;
    int r1 = 2;
    while(r1 <= x)  {
        ret++;
        r1 <<= 1;
    }
    return ret;
}

int gcd(int a, int b)  {
    if(b == 0)
        return a;

    return gcd(b, a % b);
}


int main()  {
    f = fopen("euclid.in", "r");
    g = fopen("euclid.out", "w");

    r(f, "%d", &T);
    for(int i = 0;i < T;i++)  {
        r(f, "%d%d%d%d", &m, &n, &h, &w);
        for(int l = 1;l <= m;l++)
            for(int c = 1;c <= n;c++)  {
                r(f, "%d", &a[l][c]);
            }

        int logm, logn;
        logm = log(m), logn = log(n);

        for(int l = 1;l <= m;l++)
            for(int c = 1;c <= n;c++)  {
                d[0][0][l][c] = a[l][c];
                d[0][1][l][c] = gcd(a[l][c], a[l][c + 1]);
                d[1][0][l][c] = gcd(a[l][c], a[l + 1][c]);
                d[1][1][l][c] = gcd(d[0][1][l][c], d[1][0][l][c]);
                d[1][1][l][c] = gcd(d[1][1][l][c], a[l + 1][c + 1]);
                for(int di = 1;l + (1 << di) - 1 <= m;di++)
                    for(int dj = 1;c + (1 << dj) - 1 <= n;dj++)  {
                        d[di][dj][l][c] = gcd(d[di - 1][dj][l][c], d[di][dj - 1][l][c]);
                        d[di][dj][l][c] = gcd(d[di - 1][dj - 1][l + 1 << (di - 1) - 1][c + 1 << (dj) - 1], d[di][dj][l][c]);
                        d[di][dj][l][c] = gcd(d[di - 1][dj][l + 1 << (di - 1) - 1][c], d[di][dj][l][c]);
                        d[di][dj][l][c] = gcd(d[di][dj - 1][l][c + 1 << (dj - 1) - 1], d[di][dj][l][c]);
                        d[di][dj][l][c] = gcd(d[di][dj][l][c], a[l][c]);
                        d[di][dj][l][c] = gcd(d[di][dj][l][c], a[l + 1 << di - 1][c + 1 << dj - 1]);
//                        printf("dreptunghiul ce incepe din l%d c%d si se termina in l%d c%d are gcd-ul %d\n", l, c, l + 1 << di - 1, c + 1 << dj - 1, d[di][dj][l][c]);
                    }
            }

        int max = 0;

        int logw, logh;
        logw = log(w), logh = log(h);
        int nrw = 1 << logw, nrh = 1 << logh;

        for(int l = 1;l <= m - h + 1;l++)
            for(int c = 1;c <= n - w + 1;c++)  {
                int cmmdc;
                cmmdc = gcd(d[logh][logw][l][c], d[logh][logw][l][c + w - nrw]);
                int cmmdc1 = gcd(d[logh][logw][l + h - nrh][c], d[logh][logw][l + h - nrh][c + w - nrw]);
                cmmdc = gcd(cmmdc, cmmdc1);
                max = Max(cmmdc, max);
            }

        pr(g, "Case #%d: %d\n", i + 1, max);
    }


    fclose(f);
    fclose(g);

    return 0;
}


Titlul: Răspuns: 504 Euclid
Scris de: Andi Arnautu din Ianuarie 08, 2017, 17:57:13
E destul de greu pentru cineva sa iti ia sursa si sa verifice unde este greseala. Ia mult timp, mai ales datorita faptului ca fiecare are un stil de codare diferit.

Cel mai bine e sa iti generezi teste mici si sa faci debug pe sursa pas cu pas ( nu sa vezi numai daca rezultatul final e OK ). Vei afla unde e greseala mai repede si te va ajuta si in concurs mult mai mult. ;) Bafta!