Cod sursa(job #1018973)

Utilizator tannous.marcTannous Marc tannous.marc Data 30 octombrie 2013 11:31:52
Problema A+B Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.21 kb
// Declarare librarii n stuff
#include <fstream>
#include <algorithm>
#include <list>
#include <climits>
using namespace std;
// Structurile punct si segment
struct punct
{
    float x,y;
};
struct segment
{
    punct sus,jos;
    float m,n;
};
typedef list<segment> coada;
typedef list<segment>::iterator ite;
coada q;
segment v[50];
// Comparator ce compara doua segmente, dupa minimul Y-urilor celor doua puncte ale fiecarui segment, iar apoi dupa minimul X-urilor celor doua segmente
bool comp(segment a,segment b)
{
    float miny1,miny2,minx1,minx2;
    miny1=min(a.jos.y,a.sus.y);
    miny2=min(b.jos.y,b.sus.y);
    minx1=min(a.jos.x,a.sus.x);
    minx2=min(b.jos.x,b.sus.x);
    if(miny1==miny2)
        return(minx1<minx2);
    else
        return(miny1<miny2);
}
// Calcularea parametrilor m si n pentru un segment a
void parametrii(segment &a)
{
    if(a.sus.x==a.jos.x) {
        a.m=INT_MAX;
        a.n = a.jos.y;
    }
    else a.m=(a.jos.y-a.sus.y)/(a.jos.x-a.sus.x);
    a.n=a.jos.y-a.sus.x*a.m;
}
// Verificare daca doua segmente se intersecteaza
bool intersect(segment a,segment b)
{
    bool true1,true2,true3,true4;
    if(a.m==b.m) return 0;
    float xintersect,yintersect;

    if(a.m==INT_MAX){
        xintersect = a.jos.x;
        yintersect=b.m*xintersect+a.n;
    }
    else if(b.m==INT_MAX){
        xintersect = b.jos.x;
        yintersect=a.m*xintersect+a.n;
    }
    else {
        xintersect=(b.n-a.n)/(a.m-b.m);
        yintersect=a.m*xintersect+a.n;
    }
    if(xintersect>=min(a.sus.x,a.jos.x) && xintersect<=max(a.sus.x,a.jos.x)) true1=1;
    if(xintersect>=min(b.sus.x,b.jos.x) && xintersect<=max(b.sus.x,b.jos.x)) true2=1;
    if(yintersect>=min(a.sus.y,a.jos.y) && yintersect<=max(a.sus.y,a.jos.y)) true3=1;
    if(yintersect>=min(b.sus.y,b.jos.y) && yintersect<=max(b.sus.y,b.jos.y)) true4=1;
    if(true1!=0 && true2!=0 && true3!=0 && true4!=0) return 1;
    else return 0;
}
// Incepe main-ul
int main()
{
// Citirea fisierelor, a numarului de segmente si definirea variabilelor
    ifstream in("b1.in");
    ofstream out("b1.out");
    int n,i,j,cnt=0;
    in>>n;
// Citirea segmentelor si determinarea parametrilor fiecaruia pt. ecuatia dreptei
    for(i=0; i<n; i++)
    {
        in>>v[i].jos.x>>v[i].jos.y>>v[i].sus.x>>v[i].sus.y;
        parametrii(v[i]);
    }
// Sortarea vectorului de segmente pentru Baleiere de jos in sus, dupa Y
    sort(v,v+n,comp);
// Determinarea punctelor de intersectie, bagand segmentele intr-o coada
    for(i=0; i<n; i++)
    {
        if(min(v[i].jos.y,v[i].sus.y)>=max(q.back().jos.y,q.back().sus.y)) q.pop_back();
        for(ite j=q.begin(); j!=q.end() ; j++)
        {
            if(intersect(v[i],*j)!=0)
            {
                cnt++;
                out<<"Segmentul de coordonate "<<v[i].jos.x<<" "<<v[i].jos.y<<" "<<v[i].sus.x<<" "<<v[i].sus.y<<" "<<"se intalneste cu segmentul de coordonate"<<" "<<(*j).jos.x<<" "<<(*j).jos.y<<" "<<(*j).sus.x<<" "<<(*j).sus.y<<endl;
            }
        }
        q.push_back(v[i]);
    }
// Afisarea numarului de puncte de intersesctie
    out<<"In total avem "<<cnt<<" puncte de intersectie.";
    in.close();
    out.close();
    return 0;
}