infoarena

infoarena - concursuri, probleme, evaluator, articole => Arhiva de probleme => Subiect creat de: Mircea Pasoi din Mai 23, 2005, 14:19:33



Titlul: 067 Triang
Scris de: Mircea Pasoi din Mai 23, 2005, 14:19:33
Aici puteţi discuta despre problema Triang (http://infoarena.ro/problema/triang).


Titlul: 067 Triang
Scris de: Vlad Berteanu din August 29, 2005, 18:54:01
Am o nedumerire la problema asta. :(
Pe exemplu:
iau punctele :
(0 0) si (4 0) obtin un al treilea varf punctul (2 3.464101651377)
iau punctele
(4,0) si (2 3.4641016) obtin un al treilea varf (1.31*10^-8 7.568*10^-9)

ambele puncte obtinute sunt foarte aproape de cele din fisierul de intrare, dar sunt diferite de la o anume zecimala in colo.
Daca e sa iau eroarea de 10^-3 cum zice in enunt imi da 2 triunghiuri, daca micsorez eroare imi da 0 triunghiuri. In enunt zice ca raspunsul este 1.

Cum trebuie sa fac ca sa o scot la capat? ](*,)


Titlul: 067 Triang
Scris de: Mircea Pasoi din August 29, 2005, 19:57:56
Citat din mesajul lui: vladcyb1
Am o nedumerire la problema asta. :(
Pe exemplu:
iau punctele :
(0 0) si (4 0) obtin un al treilea varf punctul (2 3.464101651377)
iau punctele
(4,0) si (2 3.4641016) obtin un al treilea varf (1.31*10^-8 7.568*10^-9)

ambele puncte obtinute sunt foarte aproape de cele din fisierul de intrare, dar sunt diferite de la o anume zecimala in colo.
Daca e sa iau eroarea de 10^-3 cum zice in enunt imi da 2 triunghiuri, daca micsorez eroare imi da 0 triunghiuri. In enunt zice ca raspunsul este 1.

Cum trebuie sa fac ca sa o scot la capat? ](*,)


Incearca ca atunci cand calculezi al treilea varf sa faci calculele astfel incat sa pierzi cat mai putina precizie. Eroarea de 10^-3 ar trebui sa fie de ajuns.


Titlul: 067 Triang
Scris de: Vlad Berteanu din August 31, 2005, 18:31:20
Hai ca am reusit sa trec de faza cu precizia, dar iau 40 de puncte restul TLE. Am facut double hashingul lui Patrascu, dar cred ca am ales valorile gresite pt dispersie. Imi poti zice si mie ce valori trebuie sa folosesc la dispersia numerelor reale?
folosesc functia h(x)=[{x*a}*M]
a=numar real (0,1)
M=dimensiunea tabelei


Titlul: 067 Triang
Scris de: Bogdan-Cristian Tataroiu din August 31, 2005, 18:58:13
Nu stiu ce sa-ti spun despre hash, dar iti recomand o solutie mult mai scurta si mai simpla in N^2 log N folosind nishte rotatii si o cautare binara.


Titlul: 067 Triang
Scris de: Vlad Berteanu din August 31, 2005, 20:58:44
Am facut cu cautare binara si iau 70 de puncte. Am cautat binar pe x si cand l-am gasit am cautat pe y binar intre punctele care au abscisa x. Se poate mai repede ca sa iau 100?  :-k


Titlul: 067 Triang
Scris de: Bogdan-Cristian Tataroiu din August 31, 2005, 21:06:56
Nu, asa am facut si eu cautarea binara. Incearca sa mai faci optimizari si, in caz ca nu faci asta deja, foloseste cautarea binara din articolul http://info.devnet.ro/articole.php?page=art&art=22


Titlul: 067 Triang
Scris de: Vlad Berteanu din Septembrie 01, 2005, 18:52:06
Am implementat cautrea binara din aricol si tot 70 de puncte iau. Nu mai am ce sa optimizez, pur si simplu iau oricare 2 puncte, le rotesc, obtin al treilea punct si dupa aia caut binar. Nu fac nici o operatie in plus. Eu cred ca problema a fost data pt hash, asa ca revin si intreb din nou, ce valori trebuie sa aleg pt dispersie?  :-k


Titlul: 067 Triang
Scris de: vladut.forum din Septembrie 02, 2005, 13:03:58
hmm daca iei TLE, s-ar putea sa fie din cauza cautarii binare.. pt unele cazuri nu se mai termina de blocat deoarece se blocheaza
da si mie sa vad secventa de cautare binara....


Titlul: 067 Triang
Scris de: Vlad Berteanu din Septembrie 02, 2005, 15:07:12
Il caut pe (xt,yt) in vectorul L care are doua campuri l.x si l.y, e vectorul cu puncte sortat.
Cod:

procedure binaryx;
var step,i:integer;
begin
step:=1;
while step<n do step:=(step shl 1);
i:=0;
 while step>0 do
  begin
  if(step+i<=n)and((l[step+i].x<xt)or(compar(l[step+i].x,xt))) then i:=i+step;
  step:=step shr 1;
  end;
 if compar(xt,l[i].x) then pz:=i
                      else pz:=1600;

end;

procedure binaryy(li,lo:integer);
var step,i:integer;
begin
step:=1;
while step<lo do step:=step shl 1;
i:=li-1;
 while step>0 do
  begin
  if (i+step<=lo)and((l[i+step].y<yt)or(compar(l[step+i].y,yt))) then i:=i+step;
  step:=step shr 1;
  end;
 if compar(l[i].y,yt) then find:=true
                      else find:=false;
 end;
 

procedure cauta(x,y:real);
begin
xt:=x; yt:=y;
binaryx(1,n);
if pz<>1600 then
 begin
  binaryy(pz-v[pz]+1,pz);
  if find then inc(rez);
  end;
 
end;




Functia compar da true daca coordonatele sunt egale.


Titlul: 067 Triang
Scris de: Filip Cristian Buruiana din Septembrie 02, 2005, 15:54:57
Si eu tot binar am cautat si tot 70 am luat, pe ultimele 3 teste TLE... Cel de-al treilea punct il gaseam insa altfel: din mijlocul segmentului celor doua puncte curente duceam o perpendiculara de lungime l * sqrt(3) / 2 in ambele directii posibile si aflam astfel coordonatele celui de-al treilea punct. Un algoritm O(N^2 log N) zic ca ar trebui sa se incadreze fara probleme in 1 secunda... dar la mine nu se incadreaza pentru ca am prea multe calcule consumatoare de timp...
   Sincer sa fiu, eu nu as incerca cu hash aici, mi se pare prea mica probabilitatea sa nu greseasca ( indiferent de cheia pe care o alegi )...

                                   bubbleSORT


Titlul: 067 Triang
Scris de: Vlad Berteanu din Septembrie 02, 2005, 17:33:24
Am facut si hashu-l ala ala al lui Knuth pt numere reale dar am luat 40 p . Restul TLE !!!!  ](*,)


Titlul: 067 Triang
Scris de: u-92 din Septembrie 02, 2005, 19:42:52
nu m-am uitat peste codul tau.. dar eu am cautat binar doar pe x, pe y am mers in stanga si in dreapta pana nu mai corespundeau coordonatele..
i = 1 to n-2
j = i+1 to n-1
cauta_binar(j+1, N);
cam asa.. nu prea stiu ce calcule consumatoare de timp ai facut.. eu am scos o ecuatie de gradul 2 de unde aflam cele 2 puncte


Titlul: 067 Triang
Scris de: Vlad Berteanu din Septembrie 02, 2005, 20:03:37
Si ai luat 100 asa? In mod normal daca am cautat binar si pe Y mie ar trebui sa-mi mearga mai repede.  :-k


Titlul: 067 Triang
Scris de: u-92 din Septembrie 02, 2005, 20:17:50
da.. am luat 100


Titlul: 067 Triang
Scris de: Vlad Berteanu din Septembrie 03, 2005, 18:29:13
asa iau 60. Problema asta kiar ma enerveaza! Ce optimizari ati mai facut pe acolo? Ati sortat cu quick-sort, nu? Deci iau oricare 2 puncte le rotesc in o(1) si caut binar atat.  ](*,)  ](*,)


Titlul: 067 Triang
Scris de: u-92 din Septembrie 05, 2005, 11:20:22
eu am sortat cu bubble sort :mrgreen: cred ca ai o greseala ceva in algoritm.. iei TLE sau WA?


Titlul: 067 Triang
Scris de: Vlad Berteanu din Septembrie 05, 2005, 14:50:02
TLE !


Titlul: 067 Triang
Scris de: cristi8 din Septembrie 05, 2005, 15:15:41
eu am facut cu hash si am luat 100..
cat despre functia de dispersie, m-am uitat acum pe sursa si  :shock: ce sa vad..

Cod:

#define EPS 0.001
#define HSIZE 30007
int hf(double dst)
{
  int ret;
  ret = dst+EPS;
  return ret%HSIZE;
}

..chiar nu stiu de ce am asa ceva in sursa..  :mrgreen:

oricum, am facut niste optimizari pe-acolo.. adica nu stergeam hashul cand treceam la alt "punct sursa".. doar ignoram ce era in el (mai castigam viteza)

..tu ce algoritm folosesti ? cum calculezi solutia ?


Titlul: 067 Triang
Scris de: Vlad Berteanu din Septembrie 06, 2005, 22:08:38
iau oricare 2 puncte, il calculez pe al treilea (care de fapt sunt doua puncte: unul pe stanga si unul pe dreapta) si acuma caut in hash.
 Hashul meu e de fapt double hash si functioneaza asa:
hash 1 are hsize=1013 si are a=(sqrt(5)-1)/2
hash 2 are hsize=2411 si are a=(sqrt(19)-2)/3

functia de dispersie este asta: cheie:=abs(trunc(frac(a*(x+y))*hsize));

Inserarea o fac astfel: pt fiecare punc calculez cele doua chei pt ca am doua formule si inserez punctul la cheia care are cele mai putine elemente introduse pana atunci.
Cautarea o fac in ambele tabele de hash dupa cheile obtinute prin formula.

NU folosesc pointeri.

Al treilea punc il calculez in O(1) cu rotire
Cam asta e tot cu hash.

Mai am si varianta cu cautare binara care are punctele sortate dupa x si la x egal sortate dupa y si pt fiecare punct obtinut din rotire caut binar dupa x si dupa aia intre punctele ce au acelasi x caut binar pe y.

Varianta cu double hash ia 60 de puncte si cea cu cautare binara ia 70 de puncte.
S-ar putea sa fie si din cauza ca scriu in Pascal


Titlul: 067 Triang
Scris de: sorin fagateanu din Septembrie 07, 2005, 07:12:00
se ia 100 si cu pascal  :-$  :-({|=


Titlul: 067 Triang
Scris de: cristi8 din Septembrie 07, 2005, 11:10:18
ma.. eu uite cum fac.. mai intai calculez d[][] (distanta intre oricare 2 puncte).. o(n^2)
dupa aia.. uite un pseudocod:
Cod:

pt i de la 1 la n-1
  pt j de la i+1 la n
    sol <- sol + hsearch(d[i][j], i, j)
    hadd(d[i][j], i, j);

unde hadd() adauga in hash ca "de la SURSA i, exista o distanta d[j] pana la punctul j"
si hsearch() cauta in hash "cate puncte exista la distanta d[j] de SURSA i si la distanta d[j] de punctul j"

fac hashul dupa distanta, si in fiecare element din hash retin distanta, punctul SURSA, si celalalt punct.


Titlul: Re: 067 Triang
Scris de: Sima Mihai Cotizo -vechi din Aprilie 03, 2006, 20:32:36
Cod:
	NR=0;	
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
{
who1=malloc(sizeof(punct));
who2=malloc(sizeof(punct));
ans1=malloc(sizeof(punct));
ans2=malloc(sizeof(punct));
*who1=rotate60(a[i],a[j]); // rotate60 roteste pe a[j] in jurul lui a[i] cu 60 de grade in sens trigonometric
ans1=bsearch(who1,a,n,sizeof(punct),compare_points);
if(ans1!=NULL)++NR;
*who2=rotate60(a[j],a[i]);
ans2=bsearch(who2,a,n,sizeof(punct),compare_points);
if(ans2!=NULL)++NR;
}

sunt qsortate inainte tot de functia din stdlib... si nu inteleg ce are  :'( ma chinui la ea de vreo 2 ore (nu puneam malloc)... acum imi numara de mai multe ori triunghiurile... ziceti-mi va rog daca asta e bine si eventual care sunt indicii intre care trebuie sa ma plimb... si btw, are complexitatea n^2 log n dar iau 3 TLE... deci trebuie ceva mai bun


Titlul: Raspuns: 067 Triang
Scris de: Filip Cristian Buruiana din Aprilie 03, 2006, 20:38:45
Pentru o pereche de indici (i,j), i < j, cauti un k > j astfel incat punctele determinate de indicii (i,j,k) sa formeze un triunghi echilateral. Merge si mai bine de O(N^2 log N), in O(N^2), daca citeai mai sus, cu o tabela de hash dubla.


Titlul: Re: 067 Triang
Scris de: Sima Mihai Cotizo -vechi din Aprilie 03, 2006, 20:43:08
...si daca si stiam ce e aia (ca de citit am citit) ;) ma rog, mersi de indicatie!  ](*,) btw, am modificat
Cod:
			ans1=bsearch(who1,a+j+1,n-j,sizeof(punct),compare_points);
nu ar trebui sa mearga?... ca nu vrea. ufff, o sa fac pana la urma cautarea binara de mana... si, de ce nu, un n^3, macar sa vad ca merge :'(


Titlul: Raspuns: 067 Triang
Scris de: ditzone din Aprilie 03, 2006, 20:47:42
E un articol pe info.devnet despre hash-uri, te poti documenta acolo :
http://info.devnet.ro/articole.php?page=art&art=27


Titlul: Raspuns: 067 Triang
Scris de: Filip Cristian Buruiana din Aprilie 03, 2006, 20:48:05
Scrie de mana cautarea binara. Daca la compare_points ai comparat corect numerele reale ( adica x == y <=> |x-y| < EPS ) atunci nu are de la ce sa fie, decat de la functia care iti returneaza cel de-al treilea varf ( al triunghiului echilateral ) pentru perechea de puncte de coordonate (i,j). Vezi k pentru o pereche (i,j) sunt intotdeauna 2 puncte care indeplinesc proprietatea cu triunghiul echilateral!


Titlul: Re: 067 Triang
Scris de: Sima Mihai Cotizo -vechi din Aprilie 03, 2006, 20:59:57
@ditzone: mersi, am sa-l studiez maine, azi am lucrat de la 9AM si... se cere o pauza
@filipb: am facut asa(am cautat un exemplu de functie compare_int si am convertit-o la compare_points):
Cod:
#define EPS 0.001
int compare_points(const void *a,const void *b) // for qsort & bsearch
{
float* arg11=(float*)a;
float* arg12=(float*)a+sizeof(float);
float* arg21=(float*)b;
float* arg22=(float*)b+sizeof(float);
if(*arg11<*arg21 || (abs(*arg11-*arg21)<EPS && *arg12<*arg22))return -1;
if(abs(*arg11-*arg21)<EPS && abs(*arg12-*arg22)<EPS)return 0;
return 1;
}
apoi, pentru perechea (i,j) fac asa: who1 va fi punctul a[j] rotit in jurul lui a de i cu 60 de grade (bine, un pointer, pe care il trimit functiei) si who2 punctul a de i  rotit in jurul lui a[j] (echivalent cu a[j] rotit 300 grade). deci verific pentru doua puncte, daca am inteles bine la ce te refereai...
si am corectat apelul:
Cod:
			ans2=bsearch(who2,a+j,n-j+1,sizeof(punct),compare_points)
si acum imi da exemplul lor  =D&gt; si pentru 4 puncte si pentru 5 puncte, dar iau WA pe 7 teste si TLE pe celelalte... de la ce sa fie?!?


Titlul: Răspuns: 067 Triang
Scris de: speedzeal din August 03, 2009, 22:00:11
Salut, e normal sa iau 10 TLE-uri cu o solutie de complexitate O(N^2 logN)?Sau solutia mea e gresita?La problema aceeasta se poate lua 100 de puncte cu o solutie de complexitate O(N^2 logN)?


Titlul: Răspuns: 067 Triang
Scris de: Andrei Grigorean din August 04, 2009, 01:58:36
Din cate stiu eu se poate lua 100 cu O(N^2 log N).


Titlul: Răspuns: 067 Triang
Scris de: irimias robert din Iulie 25, 2010, 17:07:11
imi puteti da si mie un pont va rog asupra aflarii coordonatelor celui de-al treilea varf al unui triunghi echilateral cand ai coordonatele celorlalte 2?


Titlul: Răspuns: 067 Triang
Scris de: Adrian Budau din Iulie 26, 2010, 17:01:28
Prima metoda ar fi sa calculezi mediatoarea(x si y al dreptei).A doua si dupa pararea mea mai simpla de inteles este cea folosind numere complexe(asta daca ai cunostinte despre ele):
Ai acolo o teorema: Un triunghi e echilateral daca numerele complexe cu afixele A,B,C(ABC fiind triunghiul in ordine trigonometrica) satisfac urmatoarea relatie:
a+eps*b+eps*eps*c=0 unde eps=cos 60+isin60;

Stiind a si b,  c poate fi:
1) -a*eps-b*eps*eps sau
2) -b*eps-a*eps*eps(considerand triunghiul in ordine invers trigonometrica).

Sper sa te ajute


Titlul: Răspuns: 067 Triang
Scris de: Cezar Mocan din Iulie 27, 2010, 07:49:36
Prima metoda mai detaliata ar suna cam asa:
Notam cu L lungimea laturii triunghiului echilateral, cu M mijlocul segmentului pe care tu il ai. Se stie ca inaltimea intr-un triunghi echilateral este egala cu L * sqrt(3) / 2. Afli ecuatia mediatoarei segmentului tau (dreapta care trece prin M si e perpendiculara pe segment) si in momentul asta te intereseaza un punct care se afla la distanta L * sqrt(3) / 2 de M (1) si satisface ecuatia mediatoarei (2).
Scriind relatiile (1) si (2) obtii un sistem de 2 ecuatii cu 2 necunoscute (coordonatele punctului). Din cauza ca sistemul o sa se reduca la o ecuatie de gradul II o sa obtii 2 solutii (varful poate fi de ambele parti ale segmentului). Sper ca am fost suficient de explicit.


Titlul: Răspuns: 067 Triang
Scris de: Andrei Grigorean din Iulie 27, 2010, 08:09:12
http://en.wikipedia.org/wiki/Rotation_matrix


Titlul: Răspuns: 067 Triang
Scris de: irimias robert din Iulie 27, 2010, 15:34:25
Multumesc mult pentru tot.

Prima metoda o cunosteam si eu, dar mi sa parut putin cam ineficienta.


Titlul: Răspuns: 067 Triang
Scris de: FMI Romila Remus Arthur din Februarie 14, 2011, 18:01:46
Am incercat sa o rezolv folosind o tabela de dispersie insa primeam Signal11 ,dupa ceva modificari am ajuns sa primesc WA.
Am modificat sursa pana am ajuns la rezolvarea in O(N^3) dar si asa primesc WA la teste.Nu stiu daca e gresita formula sau e o problema de precizie(desi nu cred ).
Formula pt a determina coordonatele celui de-al 3-lea puct este :  
Cod:
x = (-x1+y1*s3+x2+y2*s3)/2;
y = (-y1-x1*s3-x2*s3+y2)/2; //cu s3 am notat radical din 3.
?(am folosit numere complexe)


Titlul: Răspuns: 067 Triang
Scris de: UAIC.VlasCatalin din Iulie 22, 2012, 10:19:09
Rog un admin sa se uite daca este in regula evaluatorul problemei, iau TLE cu complexitatea O( N^2logN ), chiar de interes am retrimis o sursa ce lua 100 cu timpi sub 200 ms si poftim rezultatul:
http://infoarena.ro/job_detail/699907
http://infoarena.ro/job_detail/770115
aceeasi sursa ruleaza mult mai lent, chiar ia TLE pe un test si asta nu mi se pare normal  :?
Aceeasi problema este si la http://infoarena.ro/problema/curcubeu.


Titlul: Răspuns: 067 Triang
Scris de: Mihai-Alexandru Dusmanu din Iulie 22, 2012, 16:42:00
Rog un admin sa se uite daca este in regula evaluatorul problemei, iau TLE cu complexitatea O( N^2logN ), chiar de interes am retrimis o sursa ce lua 100 cu timpi sub 200 ms si poftim rezultatul:
http://infoarena.ro/job_detail/699907
http://infoarena.ro/job_detail/770115
aceeasi sursa ruleaza mult mai lent, chiar ia TLE pe un test si asta nu mi se pare normal  :?
Aceeasi problema este si la http://infoarena.ro/problema/curcubeu.

Done, am modificat eu limitele de timp (la ambele). Uneori evaluatorul merge mai prost :). De acum incolo te rog sa postezi astfel de probleme aici (http://infoarena.ro/calibrare-limite-de-timp).


Titlul: Răspuns: 067 Triang
Scris de: Bodnariuc Dan Alexandru din Iulie 25, 2012, 14:02:20
eu am alta idee care nustiu cum se face am tot incercat pe foaie da nu merge:
deci iau 2 puncte ,calculez panta si incerc sa rotesc dreapta cu 90 de grade . astfel pot afla ecuatia dreptei.
stiu ca se poate si altcumva dar eu sunt curios cum se roteste o dreapta la care i cunosti panta please help.
mersi anticipat


Titlul: Răspuns: 067 Triang
Scris de: Pirtoaca George Sebastian din Iulie 25, 2012, 14:38:37
Stii panta dreptrei (si neaparat un punct A care apartine dreptei, eventual mijlocul segmentului). Ai formula care spune ca daca doua drepte sunt perpendiculare atunci produsul pantelor este -1, deci afli panta noii drepte. Cunosti panta si un punct <=> ecuatia dreptei este d : y-yA=md(x-xA) .
Insa abordarea este greoaie si se poate pierde precizie . Daca ai notiuni de baza despre numere complexe , stii condititia ca un triunghi sa fie echilateral si gradul de dificultate al problemei se reduce foarte mult.


Titlul: Răspuns: 067 Triang
Scris de: Bodnariuc Dan Alexandru din Iulie 25, 2012, 14:54:25
hmm o sa citesc despre numere complexe sti vrun articol pe net bun? (pe romana) oricum eu inca is curios cum rotesti o dreapta cu o panta anume(nu numa sa o rotesti cu 90*) sa zicem ca cu 45* :).
mersi.


Titlul: Răspuns: 067 Triang
Scris de: Pirtoaca George Sebastian din Iulie 25, 2012, 15:03:09
Uite aici un articol despre numere complexe : http://bacmd.com/attachments/186_numere_complexe.pdf .
Este destul de bun din cate am citit eu. Cat despre a doua intrebare... Stii ca tg a = m unde m=unghiul dintre axa OX si dreapta. Aflii unghiul a, si aduni/ scazi unghiul de rotatie, deci stii noua panta (trebuie sa tratezi cazurile particulare = atunci cand nu exista tangenta, si sa vezi in ce cadran(e) se afla segmentul.


Titlul: Răspuns: 067 Triang
Scris de: Dragos-Alin Rotaru din Iulie 25, 2012, 15:50:34
In principiu e bine sa te gandesti la un numar complex (de forma A + Bi) ca fiind un vector care porneste din origine cu coordonatele A(pe axa OX) si B(pe axa OY) .
Geometric, inmultirea cu i a unui vector "stand" pe o axa reprezinta de fapt rotirea sa cu 90 de grade (adica pe axa urmatoare din stanga), de unde si faptul ca i^2 = -1 ( 1 * i * i = -1).
Nu am vazut asta in articolul dat de George si m-am gandit ca ar prinde bine cuiva. :)


Titlul: Răspuns: 067 Triang
Scris de: Petru Trimbitas din Octombrie 27, 2012, 11:56:30
Cred ca ar merge marita putin limita de timp :)