infoarena

infoarena - concursuri, probleme, evaluator, articole => Arhiva de probleme => Subiect creat de: ditzone din Octombrie 15, 2006, 21:30:02



Titlul: 285 Geometry
Scris de: ditzone din Octombrie 15, 2006, 21:30:02
Aici puteţi discuta despre problema Geometry (http://infoarena.ro/problema/geometry).


Titlul: Raspuns: 285 Geometry
Scris de: Rimovecz Ioan Mihai din Octombrie 17, 2006, 12:38:58
Poate sa-mi explice si mie cineva ce e gresit in urmatoarea sursa. Am luat in considerare toate cazurile cand segmentele se intersecteaza is paralele sau segmentele is pe aceasi dreapta si iau doar 20p?? :readthis:
Cod:
const fis='geometry';
      nmax=500;
var x1,x2,y1,y2,a,b,c:array[1..nmax] of longint;
    n,rez:longint;

Procedure read_data;
var i:longint;
begin
readln(n);
for i:=1 to n do
    begin
    readln(x1[i],y1[i],x2[i],y2[i]);
    a[i]:=y2[i]-y1[i];
    b[i]:=x2[i]-x1[i];
    c[i]:=(x1[i]*y2[i])-(x2[i]*y1[i]);
    end;
end;

Procedure compute;
var i,j:longint;
    y:real;

Function peg(n1,n2:longint):boolean;
begin
if a[n1]*b[n2]=a[n2]*b[n1]
then peg:=true
else peg:=false;
end;

Function ini(aa,bb:longint;c:real):boolean;
var a,b:longint;
begin
if aa<=bb
then begin
     a:=aa;
     b:=bb;
     end
else begin
     a:=bb;
     b:=aa;
     end;
if (a<=c) and (c<=b)
then ini:=true
else ini:=false;
end;

begin
for i:=2 to n do
    for j:=1 to i-1 do
        if peg(i,j)
        then begin
             if (c[i]=c[j]) and (ini(x1[i],x2[i],x1[j]) or
             ini(x1[i],x2[i],x2[j]) or ini(x1[j],x2[j],x1[i]) or ini(x1[j],x2[j],x2[i]))
             then inc(rez);
             end
        else begin
             y:=((c[j]*a[i])-(c[i]*a[j]))/((b[i]*a[j])-(b[j]*a[i]));
             if ini(y1[i],y2[i],y) and ini(y1[j],y2[j],y)
             then inc(rez);
             end;
end;

begin
assign(input,fis+'.in');
reset(input);
assign(output,fis+'.out');
rewrite(output);
read_data;
compute;
writeln(rez);
close(output);
close(input);
end.


Titlul: Raspuns: 285 Geometry
Scris de: u-92 din Octombrie 17, 2006, 13:51:19
nu inteleg ce faci tu.. dar iti sugerez sa incerci cu produs incrucisat, cred ca e cel mai comod. AB se intersecteaza cu CD daca (A, C, B) * (A, D, B) <= 0 si (D, A, C) * (D, B, C) <= 0

unde (A, B, C) = AB x AC


Titlul: Raspuns: 285 Geometry
Scris de: Savin Tiberiu din Octombrie 28, 2006, 15:37:00
nu vreau sa insinuez nimik doar ca fapt divers eu am luat 100 de pct cu un program care ptr testul:

4
-1 -1 1 1
0 -1 0 1
-1 0 1 0
5 5 6 6

afiseaza 4, si ar trebuie sa afiseze 3, deoarece considera ca primul segment se intersecteaza cu ultimul si ele de fapt nu se intersecteaza.

PS : folosesc ecuatia dreptei


Titlul: Raspuns: 285 Geometry
Scris de: Andrei Grigorean din Octombrie 28, 2006, 16:46:16
majoritatea programelor care nu folosesc respingere rapida pica asemenea teste :P.

vezi in cormen cu respingerea rapida  :peacefingers:


Titlul: Răspuns: 285 Geometry
Scris de: Andrei Homorodean din Iunie 06, 2007, 15:59:24
Este un 3 in plus pe prima linie in exemplu.

L.E.: acum e ok :P


Titlul: Răspuns: 285 Geometry
Scris de: Sturzu Antonio-Gabriel din Septembrie 22, 2007, 21:34:05
Poate sa-mi zica si mie cineva ce au asa special testele de la 5 in sus ca mai mult de 40 de puncte nu iau
desi fac cu produs incrucisat si respingere rapida ](*,)


Titlul: Răspuns: 285 Geometry
Scris de: Bogdan-Alexandru Stoica din Septembrie 23, 2007, 22:02:20
iei tle sau wa? (testele nu au nimic special)


Titlul: Răspuns: 285 Geometry
Scris de: Sturzu Antonio-Gabriel din Septembrie 24, 2007, 12:25:01
Iau WA si nu-mi dau seama ce gresesc,fac exact cum zice in Cormen.Gresesc undeva?


Titlul: Răspuns: 285 Geometry
Scris de: Hasna Robert din Septembrie 25, 2007, 22:23:59
Eu am testat intersectia a 2 seg cu arii si cu respingere rapida.prima data facem respingerea apoi am calculat aria cu semn a unui triunghi format din primul segment si un punct din al doilea segment si aria triunghiului format din acelasi segment(adik primu`) cu al doilea punct.Daca aveau acelasi semn segmentele nu se puteau intersecta.Apoi am luat cel de-al doilea segment si cu punctele care formau primul segment si calculam ariile si din nou  daca aveau ac semn , seg nu se intersectau.daca trecea de testele acestea, inseamna ca segmentele se intersectau.Nu trebe neaparat aria, ideea era ca punctele sa fie de cele 2 parti ale segmentului, dar mie mi s-a parut mai usor sa explic folosind arii, dar merge la fel ed bine cu produs incrucisat.
Si am luat doua "for", daca seg i se inters cu seg j incrementam rezultatul.
Si am luat 100  :D :peacefingers: :yahoo:

Poate va ajuta ideea asta  :wink:


Titlul: Răspuns: 285 Geometry
Scris de: Sergiu-Ioan Ungur din Martie 29, 2009, 00:53:06
Imi poate spune cineva conditia de intersectie a doua segmente sau unde o pot gasi. Daca nu se poate pe forum macar mesaj privat. I'as fi recunoscator celui ce m'ar ajuta.


Titlul: Răspuns: 285 Geometry
Scris de: Sima Cotizo din Martie 29, 2009, 01:09:26
Daca ai segmentele [AB] si [CD], trebuie sa ai conditiile A si B de o parte si de cealalta a dreptei CD si C si D de o parte si de cealalta a dreptei AB. Cu alte cuvinte, cand introduci punctele A si B in ecuatiile dreptei CD, produsul rezultatelor trebuie sa fie negativ (si analog pt celalalt caz).


Titlul: Răspuns: 285 Geometry
Scris de: Andrei Misarca din Martie 29, 2009, 08:54:42
Aici (http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry2) gasesti tutorialu de geometrie de pe topcoder. Poti face intersectia dreptelor suport ale segmentelor, iar apoi verifici daca punctu de intersectia apartine ambelor segmente


Titlul: Răspuns: 285 Geometry
Scris de: Sergiu-Ioan Ungur din Martie 29, 2009, 11:49:45
Va multumesc mult! Am reusit sa iau 100  :yahoo:.


Titlul: Răspuns: 285 Geometry
Scris de: Oncescu Costin din Mai 28, 2012, 12:03:51
Ma poate ajuta si pe mine cineva?Sa imi dea un test mai mare sau sa-mi zica unde am gresit ca nu imi merg decat testele 1,2 si 4 si nu gasesc nici o greseala

Cod:
#include<cstdio>
using namespace std;
int n,nr,i,j,a[3],b[3],c[3],x1[502],x2[502],y1[502],y2[502];
double m[503];
double av,bv,eps;
double abs(double val)
{
if(val<0) return val*-1;
return val;
}
void detec(int x1,int y1,int x2,int y2,int p)
{
a[p]=y1-y2;
b[p]=x2-x1;
c[p]=x1*y2-y1*x2;
}
void inter(int a1,int b1,int a2,int b2,int x1,int y1,int x2,int y2)
{
detec(a1,b1,a2,b2,1);
detec(x1,y1,x2,y2,2);
bv=double(c[2]*a[1]-c[1]*a[2])/(b[1]*a[2]-b[2]*a[1]);
av=double(-b[1]*bv-c[1])/a[1];
}
int ap(int x1,int y1,int x2,int y2,double a2,double b2)
{
if((a2>=x1&&a2<=x2)||(a2<=x1&&a2>=x2)) ;
else return 0;
if((b2>=y1&&b2<=y2)||(b2<=y1&&b2>=y2)) ;
else return 0;
return 1;
}
int main()
{
freopen("geometry.in","r",stdin);
freopen("geometry.out","w",stdout);
scanf("%d",&n);
eps=0.0001;
for(i=1;i<=n;i++)
{
scanf("%d",&x1[i]);
scanf("%d",&y1[i]);
scanf("%d",&x2[i]);
scanf("%d",&y2[i]);
if(x2[i]!=x1[i]) m[i]=(double)(y2[i]-y1[i])/(x2[i]-x1[i]);
else m[i]=-1;
}
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
{
if((double)abs((double)m[i]-m[j])>eps)
{
inter(x1[i],y1[i],x2[i],y2[i],x1[j],y1[j],x2[j],y2[j]);
if(ap(x1[i],y1[i],x2[i],y2[i],av,bv)==1&&ap(x1[j],y1[j],x2[j],y2[j],av,bv)==1) nr++;
}
else
//{
//detec(x1[i],y1[i],x2[i],y2[i],1);
if(ap(x1[i],y1[i],x2[i],y2[i],x1[j],y1[j])==1||ap(x1[i],y1[i],x2[i],y2[i],x2[j],y2[j])==1) nr++;
//}
}
printf("%d\n",nr);
return 0;
}


Titlul: Răspuns: 285 Geometry
Scris de: Pirtoaca George Sebastian din Iunie 19, 2012, 16:05:25
Am gasit ceva interesant despre algoritmi si probleme de geometrie computationala aici :
http://campion.edu.ro/arhiva/index.php?page=paper&action=view&id=41
Sper sa fie de folos.


Titlul: Răspuns: 285 Geometry
Scris de: Salajan Razvan din Octombrie 15, 2012, 17:28:06
Salut! Iau incorect pe primul test si nu ma prind de ce.
Solutia mea e cam asa : iau fiecare pereche de 2 segmente si vad daca se intersecteaza;
Verific daca doua segmente se intersecteaza astfel : iau un segment si vad daca punctele care determine celalalt segment se afla in semiplane opuse fata de segmentul ales.

L.E. : Mi-a iesit pana la urma.


Titlul: Răspuns: 285 Geometry
Scris de: onisim necula din Octombrie 25, 2012, 20:38:49
Imi poate spune si mie cineva ce gresesc la problema aceasta?
Iau ok doar pe  3 teste.
Cod:
#include<algorithm>
#include<fstream>
using namespace std;
ifstream f("geometry.in");
ofstream g("geometry.out");
int i,e,j,n,nr,ok,v[200];
struct pc{int x,y;};
pc a[510],b[510];
int s(pc a,pc b,pc c)
{
    return a.y*(c.x-b.x)-a.x*(c.y-b.y)+b.x*c.y-c.x*b.y;
}
int inter(pc a1,pc b1,pc a2,pc b2)
{
    return (s(a2,a1,b1)*s(b2,a1,b1)<=0&&s(a1,a2,b2)*s(b1,a2,b2)<=0);
}
int main()
{
    f>>n;
    for(i=1;i<=n;++i)
    {
        f>>a[i].x>>a[i].y>>b[i].x>>b[i].y;
    }
    for(i=1;i<=n;++i)
    for(j=i+1;j<=n;++j)
    if(inter(a[i],b[i],a[j],b[j]))
    ++nr;
    g<<nr<<'\n';
    return 0;
}


Titlul: Răspuns: 285 Geometry
Scris de: Vasilut Lucian din Octombrie 26, 2012, 22:21:58
 Buna seara  :) .AM folosit la problema asta o metoda cu determinanti(sarrus) insa nu iau decat 3 teste :'(

Sunt atent la toate atribuirile,variabilele sunt toate de tip double ,nu stiu de ce nu merge ](*,)

Vreo sugestie ceva?
Multumesc  :)

L.E  :D variabilele nu erau toate de tip double,dupa ce le-am facut de tip double iau 50 pct cu Incorrect doar pe 1 test...
L.E2

Imi poate spune si mie cineva ce gresesc la problema aceasta?
Iau ok doar pe  3 teste.



Onisim pune in structura double la x si y ,iar functia aia s cred ca trebuie sa fie de tip double  :?

O seara placuta!!!


Titlul: Răspuns: 285 Geometry
Scris de: onisim necula din Octombrie 27, 2012, 16:11:28
ms o sa incerc!!


Titlul: Răspuns: 285 Geometry
Scris de: onisim necula din Octombrie 30, 2012, 10:00:52
am modificat si tot 0 pct
;
 :readthis:
Cod:
#include<algorithm>
#include<fstream>
using namespace std;
ifstream f("geometry.in");
ofstream g("geometry.out");
int i,e,j,n,nr,ok,v[200];
struct pc{double x,y;};
pc a[510],b[510];
double s(pc a,pc b,pc c)
{
    return a.y*(c.x-b.x)-a.x*(c.y-b.y)+b.x*c.y-c.x*b.y;
}
double inter(pc a1,pc b1,pc a2,pc b2)
{
    return (s(a2,a1,b1)*s(b2,a1,b1)<=0&&s(a1,a2,b2)*s(b1,a2,b2)<=0);
}
int main()
{
    f>>n;
    for(i=1;i<=n;++i)
    {
        f>>a[i].x>>a[i].y>>b[i].x>>b[i].y;
    }
    for(i=1;i<=n;++i)
    for(j=i+1;j<=n;++j)
    if(inter(a[i],b[i],a[j],b[j]))
    ++nr    g<<nr<<'\n';
    return 0;
}
:angry:


Titlul: Răspuns: 285 Geometry
Scris de: Vasilut Lucian din Noiembrie 01, 2012, 13:04:39
 :) Salut.Ce are mai special testul 1 ? doar pe el iau incorrect  ](*,)


Titlul: Răspuns: 285 Geometry
Scris de: Guianu Leon din Noiembrie 09, 2012, 14:53:47
Si eu m-am blocat la primul test. Un hint ar fi foarte apreciat!  :'(


Titlul: Răspuns: 285 Geometry
Scris de: Radu-Andrei Szasz din Noiembrie 09, 2012, 18:58:11
Pentru cei care picati primul test, aveti grija cand determinati punctul de intersectie sa faceti coordonatele ca lumea. Eu acolo greseam.

Incercati testul asta:
Cod:
3
0 -2 0 2
0 0 2 0
0 3 2 0

Raspuns: 2


Titlul: Răspuns: 285 Geometry
Scris de: Guianu Leon din Noiembrie 09, 2012, 19:55:27
Pentru cei care picati primul test, aveti grija cand determinati punctul de intersectie sa faceti coordonatele ca lumea. Eu acolo greseam.

Incercati testul asta:
Cod:
3
0 -2 0 2
0 0 2 0
0 3 2 0

Raspuns: 2

Imi da bine pe testul tau! Si totusi pic testul 1.  :'(


Titlul: Răspuns: Raspuns: 285 Geometry
Scris de: Salajan Razvan din Noiembrie 09, 2012, 20:54:45
Ia incearca testul asta :

4
-1 -1 1 1
0 -1 0 1
-1 0 1 0
5 5 6 6

afiseaza 4, si ar trebuie sa afiseze 3, deoarece considera ca primul segment se intersecteaza cu ultimul si ele de fapt nu se intersecteaza.

Pentru a-l lua citeste mesajul lui wefgef
majoritatea programelor care nu folosesc respingere rapida pica asemenea teste :P.

vezi in cormen cu respingerea rapida  :peacefingers:


Titlul: Răspuns: Raspuns: 285 Geometry
Scris de: Guianu Leon din Noiembrie 10, 2012, 17:36:34
Ia incearca testul asta :

4
-1 -1 1 1
0 -1 0 1
-1 0 1 0
5 5 6 6

afiseaza 4, si ar trebuie sa afiseze 3, deoarece considera ca primul segment se intersecteaza cu ultimul si ele de fapt nu se intersecteaza.

Pentru a-l lua citeste mesajul lui wefgef
majoritatea programelor care nu folosesc respingere rapida pica asemenea teste :P.

vezi in cormen cu respingerea rapida  :peacefingers:

Ai avut dreptate! A mers!  :shock:


Titlul: Răspuns: 285 Geometry
Scris de: Segarceanu Calin din Decembrie 19, 2012, 10:30:53
Imi explica si mie cineva in ce consta respingerea rapida si cum ar trebuii implementata?


Titlul: Răspuns: 285 Geometry
Scris de: Bodnariuc Dan Alexandru din Decembrie 28, 2012, 16:18:03
am o intrebare legata de produsul vectorial a 2 vectori am gasit ca e egal cu |a|*|b|*sin(X) unde X e unghiul dintre cele 2 drepte, de aici rezulta ca daca unghiul e intre 90 si 180 atunci produsul e negativ dar totusi sa luam dreapta suport pe axa ox cu originea in O si un punct in cadranul 1 si unu in cadranul 2. atunci un produs da negativ si unul pozitiv dar ambele puncte se afla pe aceiasi parte a dreptei...mersi anticipat  :D


Titlul: Răspuns: 285 Geometry
Scris de: Pirtoaca George Sebastian din Ianuarie 04, 2013, 18:10:33
Daca este vorba despre drepte atunci doua drepte se intersecteaza daca si numai daca pantele lor difera.
Panta unei drepte determinata de 2 puncte este :
m=(yB-yA) / (xB-xA);


Titlul: Răspuns: 285 Geometry
Scris de: Pirtoaca George Sebastian din Ianuarie 04, 2013, 18:13:20
Fii atent ca in problema se lucreaza cu segmente nu cu drepte.


Titlul: Răspuns: 285 Geometry
Scris de: Prehari Romica din Februarie 18, 2013, 20:17:11
imi da si mie cineva un exemplu ca la testul 1 ca sa imi dau seama de ce il tot pic? ](*,)
folosesc formula de intersectie a doua segmente dar nu imi dau seama de ce nu il iau si pe primul test :angry:


Titlul: Răspuns: 285 Geometry
Scris de: onisim necula din Februarie 20, 2013, 20:53:24
Fa testul de respingere rapida.
Asta am facut si eu.


Titlul: Răspuns: 285 Geometry
Scris de: Prehari Romica din Februarie 20, 2013, 22:06:31
Nu inteleg ce inseamna "respingere rapida", dar am pus o conditie ca pentru testul:
4
1 1 2 2
3 3 4 4
-1 1 -3 3
3 -3 6 -6
sa imi afiseze 0 si am luat si primul test :winner1:


Titlul: Răspuns: 285 Geometry
Scris de: Carabian Ovidiu din Martie 03, 2013, 15:48:36
Care ii faza cu "respingerea rapida" ? Am si eu probleme cu testul 1, si nu pricep care ii problema.  
RE : romyk pentru primul test, out = 3 nu 0;


Titlul: Răspuns: 285 Geometry
Scris de: Prehari Romica din Martie 05, 2013, 00:22:04
Nu ziceam de primul test de la evaluator ci de testul care l-am facut eu. Pentru el ar trebui sa afiseze 0. Daca folosesti doar formula de intersectie a segmentelor nu iei acest test(nu am idee de ce). Daca faci pe foaia o sa vezi ca trebuie sa iti dea 0.


Titlul: Răspuns: 285 Geometry
Scris de: Ion Ureche din August 21, 2014, 21:01:07
Probabil că ar trebui îmbunătățite testele. Am luat 100 cu sursa care nu verifica cazul în care segmentele ce se intersectau erau coliniare.


Titlul: Răspuns: 285 Geometry
Scris de: Stelian Stere din August 26, 2015, 14:53:29
Iau toate testele in afara de Testul 4. Sunt convins ca este corect matematic implementat. Nu stiu ce imi scapa.


Titlul: Răspuns: 285 Geometry
Scris de: Bogdan Ciobanu din August 27, 2015, 18:53:38
Nu m-am uitat foarte atent in sursa ta, dar iti sugerez sa compari numerele reale folosind epsilon (http://stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison).


Titlul: Răspuns: 285 Geometry
Scris de: seretan cristian din Martie 30, 2017, 21:19:22
#include<iostream>
#include<fstream>
using namespace std;
struct element
{
   long long  x1,y1,x2,y2;
};
element v[10000];
int verificare(int i,int j)
{
   int ok=0,a1,a2,b1,b2,c1,c2;
   a1=v.y2-v.y1;
   b1=v.x2*(-1)+v.x1;
   c1=v.y1*v.x2-v.y2*v.x1;
   a2=v[j].y2-v[j].y1;
   b2=v[j].x2*(-1)+v[j].x1;
   c2=v[j].y1*v[j].x2-v[j].y2*v[j].x1;
   if((a1*v[j].x1+b1*v[j].y1+c1)*(a1*v[j].x2+b1*v[j].y2+c1)<=0)
   {
      if((a2*v.x1+b2*v.y1+c2)*(a2*v.x2+b2*v.y2+c2)<=0)
      {
         ok=1;
      }
   }
   return ok;
}
int conditie1(int i,int j)
{
   float n1,n2,ok=0;
   n1=(float)(v.y2-v.y1)/(v.x2-v.x1);
   n2=(float)(v[j].y2-v[j].y1)/(v[j].x2-v[j].x1);
   if(n1!=n2)
   {
      ok=1;
   }
   return ok;
}
   
   
int main()
{
   
   long long n,i,j,nr=0;
   fstream f("geometry.in",ios::in);
   f>>n;
   for(i=1;i<=n;i++)
   {
      f>>v.x1>>v.y1>>v.x2>>v.y2;
   }
   f.close();
   for(i=1;i<n;i++)
   {
      for(j=i+1;j<=n;j++)
      {
         if(conditie1(i,j)==1)
         {
         if(verificare(i,j)==1)
         {
            nr++;
         }
         }
      }
      
   }
   fstream g("geometry.out",ios::out);
   g<<nr;
   g.close();
}


Titlul: Răspuns: 285 Geometry
Scris de: seretan cristian din Martie 30, 2017, 21:19:53
o solutie de 100 puncte


Titlul: Răspuns: 285 Geometry
Scris de: seretan cristian din Martie 30, 2017, 21:20:19
o solutie de 100