Afişează mesaje
|
Pagini: 1 [2] 3 4 5
|
26
|
infoarena - concursuri, probleme, evaluator, articole / Arhiva de probleme / Răspuns: 497 Mosia
|
: Februarie 28, 2010, 22:05:50
|
Asta-i tot ceea ce am reusit sa implementez, dar nu obtin decat 40 de p. Sortarea este cea de la infasuratoarea convexa. Scanarea Graham. s1[1] = c[1]; //s1[i] = suma maxima editandu-se primii i pari, c[i] = aria pe care o castiga prin mutarea parului i sm1[1] = 1; // sm1[i] = retine 1 daca s-a mutat parul i, 0 in caz contrar if(c[1] > c[2]) s1[2] = c[1], sm1[2] = 0; else s1[2] = c[2], sm1[2] = 1; for(int i=3;i<n;i++) { if(s1[i-2] + c[i] > s1[i-1]) s1[i] = s1[i-2] + c[i], sm1[i] = 1; else s1[i] = s1[i-1], sm1[i] = 0; } s2[2] = c[2]; sm2[2] = 1; if(c[2] > c[3]) s2[3] = c[2], sm2[3] = 0; else s2[3] = c[3], sm2[3] = 1; for(int i=4;i<=n;i++) { if(s2[i-2] + c[i] > s2[i-1]) s2[i] = s2[i-2] + c[i], sm2[i] = 1; else s2[i] = s2[i-1], sm2[i] = 0; } smax1 = s1[n-1]; smax2 = s2[n]; if(!(sm1[1]) && !(sm1[n-1])) smax1 += c[n]; if(!(sm2[2]) && !(sm2[n])) smax2 += c[1];
float smax = max(smax1, smax2); inline bool cmp(int a, int b) { return (float)(x[a] - x[PI])*(y[b] - y[PI]) < (float)(x[b] - x[PI])*(y[a] - y[PI]); }
for(int i=1;i<=n;i++) { if(i == PI) continue; IN[++IN[0]] = i; } sort(IN + 1, IN + IN[0] + 1, cmp); IN[++IN[0]] = PI; for(int i=1;i<=n;i++) { int dr = i+1, st = i-1; if(dr > n) dr = 1; if(st < 1) st = n; float D = (float)dist((float)x[IN[st]], (float)y[IN[st]], (float)x[IN[dr]], (float)y[IN[dr]]); c[i] = (float)(D * d[IN[i]]) / 2; }
|
|
|
30
|
infoarena - concursuri, probleme, evaluator, articole / Informatica / Răspuns: Problema Sortare
|
: Februarie 25, 2010, 18:04:34
|
Pai sortezi o data dupa coloane si apoi dupa linii. Dupa linii poti sa faci cu sort din stl: sort(a[0], a[0]+m, cmp), unde a[0] reprezinta prima linie, m - numarul de elemente de pe linie iar cmp functia de comparare. Daca nu pui nimic la parametrul final, atunci o sa sorteze crescator.
|
|
|
31
|
infoarena - concursuri, probleme, evaluator, articole / .CAMPION / 375 Zmeu
|
: Februarie 25, 2010, 15:30:10
|
Salut! Cum pot optimiza problema aceasta? http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=375Iau 90 de p, la testul 9 depasesc timpul. Nu stiu exact unde pierd mai mult timp, ori la Dijkstra ori la permutari. #include <fstream> #include <algorithm> #include <vector> #include <iostream> #define fin "zmeu.in" #define fout "zmeu.out" #define nMax 1001 #define Inf 200001
using namespace std;
int A[nMax][nMax]; int D[6][nMax]; int s[nMax]; int Porti[6];
int n, m, p; int F[6], FF; int I[nMax];
void citeste() { fstream in(fin, ios::in); in>>n>>m>>p>>FF; for(int i=1;i<=5;i++) in>>F[i]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i==j) A[i][j] = 0; else A[i][j] = Inf; for(int i=1;i<=m;i++) { int x, y, c; in>>x>>y>>c; A[x][y] = A[y][x] = c; } for(int i=1;i<=p;i++) in>>I[i]; in.close(); }
void Dijkstra(int nod, int f) { memset(s, 0, sizeof(s)); s[nod] = 1; for(int i=1;i<=n;i++) D[f][i] = A[nod][i]; for(int i=1;i<n;i++) { int min = Inf, jmin; for(int j=1;j<=n;j++) if(!s[j]) if(min>D[f][j]) { min = D[f][j]; jmin = j; } s[jmin] = 1; for(int j=1;j<=n;j++) if(!s[j]) if(D[f][j] > min + A[jmin][j]) D[f][j] = min + A[jmin][j]; } }
void solve() { for(int i=1;i<=5;i++) Dijkstra(F[i], i); vector<int> sol; vector<int>::iterator it; for(int i=1;i<=5;i++) sol.push_back(i); for(int i=1;i<=5;i++) { int min = Inf; for(int j=1;j<=p;j++) if(min > D[i][I[j]]) min = D[i][I[j]]; Porti[i] = min; } int Dist = Inf; do { int d; d = D[sol[0]][FF] + D[sol[1]][F[sol[0]]] + D[sol[2]][F[sol[1]]] + D[sol[3]][F[sol[2]]] + D[sol[4]][F[sol[3]]]; d += Porti[sol[4]]; if(d < Dist) Dist = d; }while(next_permutation(sol.begin(), sol.end())); fstream out(fout, ios::out); out<<Dist<<endl; out.close(); }
void tipar() { for(int i=1;i<=5;i++) cout<<Porti[i]<<" "; cout<<endl; }
int main(void) { citeste(); solve(); //tipar(); return 0; }
|
|
|
34
|
infoarena - concursuri, probleme, evaluator, articole / .CAMPION / 570 program1
|
: Februarie 22, 2010, 15:20:48
|
Salut! Program1 : http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=570Cand verific programul pe .Campion nu obtin decat 40p, iar cand downloadez testele pe care le considera eronate si le verific pe calculator obtin rezultatul corect! list<int> C; // coada list<int> L[nMax]; // lista de adiacenta int s[nMax]; // s[i] = 1 , nodul i vizitat si 0 daca nodul i nu este vizitat int lnc=0; //linia curenta
void citeste() { fstream in(fin, ios::in); char instr[21]; while(in.getline(instr, nMax, '\n')) { if(instr[0] != '.') { lnc++; int k=0; // nr de cuv din instructiune, instrctiunea se incadreaza in tipul instructiunii cu k cuvinte char cmd[4][6]; char *p=strtok(instr, " "); while(p) { strcpy(cmd[++k], p); p=strtok(NULL, " "); } switch(k) { case 1: L[lnc].push_back(lnc+1); break; case 2: L[lnc].push_back(atoi(cmd[2])); break; case 4: L[lnc].push_back(atoi(cmd[2])); L[lnc].push_back(atoi(cmd[4])); break; } } } in.close(); }
void bfs(int nod) { s[nod] = 1; C.push_back(nod); while(C.size()) { list<int>::iterator it; for(it=L[*C.begin()].begin();it!=L[*C.begin()].end();it++) { if(!s[*it]) { s[*it] = 1; C.push_back(*it); } } C.pop_front(); } } Construiesc un graf si apoi il parcurg cu BF. La sfarsit verific cate noduri au ramas nevizitate si afisez rezultatul!
|
|
|
37
|
infoarena - concursuri, probleme, evaluator, articole / Informatica / Răspuns: SumDif
|
: Februarie 06, 2010, 02:05:50
|
Multumesc pentru raspuns, deja am apucat sa scriu o dinamica care am observat ca rezolva corect, complexitatea de timp in cazul cel mai nefavorabil este O(N^3), insa ce ma intereseaza cel mai mult este complexitatea de spatiu, primesc killed by signel 11; Sol[ i ][ j ] = valoarea maxima dintre diferenta sumelor celor doua submultimi daca cardinalul primei multimi este i si se adauga la suma maxima obtinuta la pasul i-1 cartea j (in prima multime); Cartea j se va adauga in urmatorul mod: La suma maxima accesibila de la pasul i-1 adunam minimul cartii (deoarec acesta a fost scazut la pasul anterior) si valoarea maxima de pe carte! Matricea s are rolul de a retine ce carti au fost utilizate pentru a obtine suma maxima utilizand cartea j. Am sa incerc sa implementez si recurenta ta, dar m-ar interesa daca ati reusi sa modificati si dinamica mea (in cazul in care se poate)! ... typedef struct { int f1; int f2; }Elem;
Elem C[nMax]; int Sol[1][nMax]; bool s[1][nMax][nMax];
void solve() { for(int i=1;i<=n;i++) { Sol[0][i] = max(C[i].f1, C[i].f2); s[0][i][i] = true; for(int j=1;j<=n;j++) if(j==i) continue; else Sol[0][i] -= min(C[j].f1, C[j].f2); } for(int i=1;i<k;i++) for(int j=1;j<=n;j++) { int maximum=-1000000, indx; for(int l=1;l<=n;l++) if(l==j) continue; else if(maximum<Sol[(i-1)%2][l]) { maximum=Sol[(i-1)%2][l]; indx=l; } int max1, min1; if(C[j].f1<C[j].f2) min1 = C[j].f1, max1 = C[j].f2; else min1 = C[j].f2, max1 = C[j].f1; for(int l=1;l<=n;l++) s[i%2][j][l] = s[(i-1)%2][indx][l]; if(!s[i%2][j][j]) Sol[i%2][j] = maximum + min1 + max1, s[i%2][j][j] = true; else Sol[i%2][j] = -1000000; } }
... Da! Mi-am dat seama ca depasesc si timpul, sursa obtine 50 de puncte.
|
|
|
41
|
infoarena - concursuri, probleme, evaluator, articole / Informatica / Răspuns: Lant graf
|
: Ianuarie 09, 2010, 23:34:31
|
Nu neaparat! Ca sa fie adevarat ceea ce spui tu, nodurile trebuie sa fie consecutive! Ar putea exista lant 1-5-3-7-9; Ca sa verifici daca exita lant de la un nod x la un nod y, aplici o parcurgere df sau bf incepand cu unul din nodurile x sau y si retii intr-un vector fie el s, nodurile vizitate! Daca ai aplicat parcurgerea incepand cu x, verifici sa vezi daca s[y] == 1. Daca da atunci exista drum de la x la y.
|
|
|
48
|
infoarena - concursuri, probleme, evaluator, articole / Informatica / Răspuns: Totul pare OK!
|
: Noiembrie 14, 2009, 23:41:12
|
Da, problema are un enunt destul de confuz! Merge mai repede algoritmul acesta: #include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int maxn = 120000; const int INF = 1000000001; double X[maxn],Y[maxn]; //long double V[maxn]; int PI,IND[maxn],N,ST[maxn]; bool cmpf(int i,int j) { return (double)(X[i] - X[PI]) * (Y[j] - Y[PI]) < (double)(X[j] - X[PI]) * (Y[i] - Y[PI]); } long double semn(int i1,int i2,int i3) { return (long double)X[i1] * Y[i2] + X[i2] * Y[i3] + X[i3] * Y[i1] - Y[i1] * X[i2] - Y[i2] * X[i3] - Y[i3] * X[i1]; } int main() { freopen("cetati.in","r",stdin); freopen("cetati.out","w",stdout); scanf("%d\n",&N); X[0] = INF;Y[0] = INF; int punct_initial = 0; for(int i = 1;i <= N; ++i) { scanf("%lf %lf",&X[i],&Y[i]); if (X[i] < X[punct_initial] || (X[i] == X[punct_initial] && Y[i] < Y[punct_initial])) punct_initial = i; } PI = punct_initial; for(int i = 1;i <= N; ++i) { if (i == punct_initial) continue; IND[++IND[0]] = i; } sort(IND + 1,IND + IND[0] + 1,cmpf); ST[ST[0] = 1] = punct_initial; for(int i = 1;i <= IND[0]; ++i) { if (IND[i] == punct_initial) continue; while(ST[0] >= 2 && semn(ST[ST[0] - 1],ST[ST[0]],IND[i]) >= 0) --ST[0]; ST[++ST[0]] = IND[i]; } ST[++ST[0]] = punct_initial; printf("%d\n",N - (int)(ST[0]-1)); /*reverse(ST + 1, ST + ST[0] + 1); for(int i = 1;i < ST[0]; ++i) { printf("%lf %lf\n",X[ST[i]],Y[ST[i]]); }*/ return 0; }
|
|
|
|