Cod sursa(job #2480962)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 26 octombrie 2019 11:58:46
Problema Laser Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 6.76 kb
/*#include <bits/stdc++.h>
using namespace std;

fstream in ( "laser.in" , ios::in  );
fstream out( "laser.out", ios::out );

const int DIM = 520;

bitset<DIM * 2> sys[DIM], ans;
pair<double, double> seg[DIM * 2], ept1[DIM], ept2[DIM];

inline double ccw( const pair<double, double> pt1, const pair<double, double> pt2, const pair<double, double> pt3 ) {
    return ( pt2.first - pt1.first ) * ( pt3.second - pt1.second ) -
           ( pt3.first - pt1.first ) * ( pt2.second - pt1.second );
}

inline bool comp( const pair<double, double> pt1, const pair<double, double> pt2 ) {
    return ccw( make_pair( 0, 0 ), pt1, pt2 ) > 0;
}

int main( void ) {

    int n, m = 0;
    in >> n;

    for( int i = 1; i <= n; i ++ ) {
        in >> ept1[i].first >> ept1[i].second;
        in >> ept2[i].first >> ept2[i].second;

        seg[++ m] = ept1[i];
        seg[++ m] = ept2[i];
    }

    for( int i = 1; i <= n; i ++ ) {
        bool x;
        in >> x;

        sys[i][m + 1] = x;
    }

    sort( seg + 1, seg + m + 1, comp );

    seg[m + 1] = seg[1];
    for( int i = 1; i <= m; i ++ ) {
        pair<double, double> pt1 = make_pair( 0, 0 );
        pair<double, double> pt2 = make_pair( ( seg[i].first  + seg[i + 1].first  ) * 10000,
                                              ( seg[i].second + seg[i + 1].second ) * 10000 );
        out<<pt2.first<<" "<<pt2.second<<"\n";
        for( int j = 1; j <= n; j ++ ) {
            if( ccw( pt1, pt2, ept1[j] ) * ccw( pt1, pt2, ept2[j] ) < 0 )
            if( ccw( ept1[j], ept2[j], pt1 ) * ccw( ept1[j], ept2[j], pt2 ) < 0 )
                sys[j][i] = true;
        }
    }
    for (int i=1;i<=n;i++,out<<endl)
        for (int j=1;j<=m+1;j++)
            out<<sys[i][j]<<" ";

    for( int i = 1, j = 1; i <= n && j <= m; ) {
        bool ok = false;

        for( int k = i; k <= n; k ++ ) {
            if( sys[k][j] == true ) {
                swap( sys[i], sys[k] );
                ok = true; break;
            }
        }

        if( ok == false )
            j ++;
        else {
            for( int k = i + 1; k <= n; k ++ )
                if( sys[k][j] == true )
                    sys[k] ^= sys[i];

            i ++; j ++;
        }
    }

    for( int i = n, j = 1; i >= 1; i --, j = 1 ) {
        while( j <= m && sys[i][j] == false )
            j ++;

        if( j <= m )
            ans[j] = sys[i][m + 1];

        for( int p = j + 1; p <= m; p ++ )
            ans[j] = ans[j] ^ ( ans[p] & sys[i][p] );
    }

    out << ans.count() << "\n";
    for( int i = 1; i <= m; i ++ ) {
        if( ans[i] == true ) {
            double ang = atan2( ( seg[i].second + seg[i + 1].second ) * 10000,
                                ( seg[i].first  + seg[i + 1].first  ) * 10000 ) * 180 / acos( -1 );
            if( ang < 0 )
                ang += 360;

            out << setprecision( 6 ) << fixed << ang << "\n";
        }
    }

    return 0;
}*/
#include <bits/stdc++.h>
#define DIM 1000
using namespace std;

ifstream fin ("laser.in");
ofstream fout ("laser.out");
struct point{
    double x,y;
};
point points[DIM];
struct segment{
    double x,y,x2,y2;
}sgm[DIM];

int a[DIM][DIM],stare[DIM],sol[DIM];
pair <double,double> dr[DIM];
int n,i,j,k;
double X1,Y1,X2,Y2;
vector <double> ans;

inline double get_det (double X1, double Y1, double X2, double Y2, double X3, double Y3){
    return (X2-X1)*(Y3-Y1) - (X3-X1)*(Y2-Y1);
}
inline double dist_org (point a){
    return a.x*a.x + a.y*a.y;
}
inline double get_dist (double x, double y, double x2, double y2){
    return sqrt ((x-x2)*(x-x2) + (y-y2)*(y-y2));
}
inline int cadran (point a){
    if (a.x > 0 && a.y >= 0)
        return 1;
    if (a.x <= 0 && a.y > 0)
        return 2;
    if (a.x < 0 && a.y <= 0)
        return 3;
    return 4;
}
inline int cmp (point a, point b){
    return get_det (0,0,a.x,a.y,b.x,b.y) > 0;
}
inline int intersectie (double x, double y, double x2, double y2, double x3, double y3){
    /// dreapta det de punctele 0,0 si x,y intersecteaza segmentul x2,y2; x3,y3
    if (get_det(0,0,x,y,x2,y2) * get_det(0,0,x,y,x3,y3) < 0 && get_det(x2,y2,x3,y3,0,0) * get_det(x2,y2,x3,y3,x,y) < 0)
        return 1;
    return 0;
}
inline int urm (int x){
    if (x < k)
        return x+1;
    return 1;
}
int main (){

    fin>>n;
    for (i=1;i<=n;i++){
        fin>>X1>>Y1>>X2>>Y2;
        points[++k] = {X1,Y1};
        points[++k] = {X2,Y2};
        sgm[i] = {X1,Y1,X2,Y2};
    }
    /// sortez punctele dupa unghi
    sort (points+1,points+k+1,cmp);
    //for (i=1;i<=k;i++)
       // fout<<points[i].x<<" "<<points[i].y<<"\n";
    /// pt fiecare pereche de puncte consecutive iau bisectoarea

    for (i=1;i<=k;i++){
        point A = points[i], B = points[urm(i)];
        double dist_ob = get_dist (0,0,B.x,B.y);
        double dist_oa = get_dist (0,0,A.x,A.y);
        double dist_ab = get_dist (A.x,A.y,B.x,B.y);
        /// bisectoarea
        double xm = A.x*dist_ob/(dist_ob+dist_oa) + B.x*dist_oa/(dist_ob+dist_oa);
        double ym = A.y*dist_ob/(dist_ob+dist_oa) + B.y*dist_oa/(dist_ob+dist_oa);

        xm *= 10000.0, ym *= 10000.0;

        /// acum vad ce segmente intersecteaza
        dr[i] = make_pair (xm,ym);
        for (int j=1;j<=n;j++){
            if (intersectie (xm,ym,sgm[j].x,sgm[j].y,sgm[j].x2,sgm[j].y2))
                a[j][i] = 1;
        }}

    for (i=1;i<=n;i++){
        fin>>stare[i];
        a[i][k+1] = stare[i];
    }

    for (i=1;i<=n;i++,fout<<"\n")
        for (j=1;j<=k+1;j++)
            fout<<a[i][j]<<" ";
    /// gauss
    int i = 1, j = 1, m = k;
    while (i <= n && j <= m){
        int lin = i;
        while (lin <= n && !a[lin][j])
            lin++;
        if (lin == n+1){
            j++;
            continue;
        }
        if (i != lin){
            for (k=1;k<=m+1;k++)
                swap (a[i][k],a[lin][k]);
        }
        for (k=i+1;k<=n;k++){
            if (a[k][j]){
                for (int t=1;t<=m+1;t++)
                    a[k][t] ^= a[i][j];
            }}
        i++, j++;
    }
    for (i=n;i;i--){
        j = 1;
        while (j <= m+1 && !a[i][j])
            j++;
        if (j == m+2)
            continue;
        sol[j] = a[i][m+1];
        for (k=j+1;k<=m;k++)
            sol[j] ^= (a[i][k]*sol[k]);
    }
    for (i=1;i<=m;i++)
        if (sol[i]){
            /// inseamna ca aleg dreapta asta
            double val = atan2 (dr[i].second,dr[i].first);
            if (val < 0)
                val += 2*3.14159265;
            val = val*180 / 3.14159265;
            ans.push_back(val);
        }
    fout<<ans.size()<<"\n";
    for (int i=0;i<ans.size();i++)
        fout<<setprecision(6)<<fixed<<ans[i]<<"\n";

    return 0;
}