kien_coi_1997

gallery.cpp

Mar 16th, 2014
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.42 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stack>
  4. #include <vector>
  5. #include <iostream>
  6. #include <algorithm>
  7. using namespace std;
  8.  
  9. #define long long long
  10. #define f1(i,n) for (int i=1; i<=n; i++)
  11. #define f0(i,n) for (int i=0; i<n; i++)
  12. typedef pair<double, double> lflf;
  13. typedef pair<lflf, double> line;
  14. #define X first
  15. #define Y second
  16.  
  17. struct vertex : lflf {
  18.     vertex *Next, *Prev;
  19.     int Visited; bool Removed;
  20.     void clear(){ Next=Prev=NULL; Visited=0; Removed=false; }
  21.     vertex(lflf a){ clear(); X=a.X, Y=a.Y; }
  22.     vertex(double x, double y){ clear(); X=x, Y=y; }
  23.     vertex(){ clear(); }
  24. };
  25.  
  26. int cnt=0, Jumps=0;
  27. void NIE(){ cout << "0.00" << endl; exit(0); }
  28. #define f2(I, A) for (vertex *I=(cnt++, A); changable(I->Visited, cnt); I=I->Next)
  29. ostream& operator << (ostream& cout, line d)
  30.     { return cout << d.X.X << "x+" << d.X.Y << "y=" << d.Y; }
  31. bool changable(int &a, int b)
  32.     { if (a==b) return false; return a=b, true; }
  33. double abs(double a, double b)
  34.     { return a>b?a-b:b-a; }
  35. lflf operator - (lflf a, lflf b)
  36.     { return lflf(a.X-b.X, a.Y-b.Y); }
  37. lflf fn(lflf a)
  38.     { return lflf(-a.Y, a.X); }
  39. line xxfd(lflf a, lflf b)
  40.     { lflf n = fn(a-b); return line(n, n.X*a.X+n.Y*a.Y); }
  41. bool ddfx(line a, line b, lflf &I){
  42.     double D = a.X.X*b.X.Y-a.X.Y*b.X.X;
  43.     if (abs(D, 0)<=1e-9) return false;
  44.     double DX = a.Y*b.X.Y-a.X.Y*b.Y;
  45.     double DY = a.X.X*b.Y-a.Y*b.X.X;
  46.     I=lflf(DX/D, DY/D);
  47.     return true;
  48. }
  49. double xdf(lflf a, line d)
  50.     { return d.X.X*a.X+d.X.Y*a.Y-d.Y; }
  51. int sign(double a)
  52.     { if (abs(a, 0)<=1e-9) return 0; return a>0?1:-1; }
  53. int sign(lflf a, line d)
  54.     { return sign(xdf(a, d)); }
  55.  
  56.  
  57. void show(vertex* A){
  58.     printf("Show()\n");
  59.     f2(I,A) printf("%X, %X, %X, %lf, %lf\n", I->Prev, I, I->Next, I->X, I->Y);
  60. }
  61. ostream& operator << (ostream& cout, vertex* a)
  62.     { return cout << a->X << "," << a->Y; }
  63. void insert(vertex* b, vertex* a){
  64.     b->Next=a->Next; a->Next->Prev=b;
  65.     a->Next=b; b->Prev=a;
  66. //  cout << "Insert " << b << endl;
  67. }
  68. void remove(vertex* a){
  69.     a->Prev->Next=a->Next;
  70.     a->Next->Prev=a->Prev;
  71. //  cout << "Remove " << a << endl;
  72.     delete a;
  73. }
  74. stack<vertex*> RemoveLater;
  75. void remove_later(vertex* a){
  76.     RemoveLater.push(a);
  77.     a->Removed=true;
  78. }
  79. void remove_now(){
  80.     while (RemoveLater.size()) {
  81.         remove(RemoveLater.top());
  82.         RemoveLater.pop();
  83.     }
  84. }
  85.  
  86. #define N 12309
  87. int n;
  88. vertex* a[N];
  89.  
  90. vertex* crop(line d, vertex* A){
  91. //  cout << "Crop " << d << ";" << A << endl;
  92.     f2(I,A) if (sign(*I, d)!=0 && sign(*I, d) + sign(*I->Next, d) == 0) {
  93. //      cout << "sign " << I << ";" << d << "=" << sign(*I, d) << endl;
  94. //      cout << "sign " << I->Next << ";" << d << "=" << sign(*I->Next, d) << endl;
  95. //      cin.ignore(1);
  96.         lflf K;
  97.         if (ddfx(d, xxfd(*I, *I->Next), K))
  98.         insert(new vertex(K), I);
  99.     }
  100.     f2(I,A) if (sign(*I, d)<0) remove_later(I);
  101.     while (A->Removed) { if (++Jumps>10000000) NIE(); A=A->Next; }
  102.     remove_now();
  103.     return A;
  104. }
  105. double area(lflf a, lflf b){
  106.     return (a.X-b.X)*(a.Y+b.Y);
  107. }
  108. double area(vertex* A){
  109.     double Sum=0;
  110.     f2(I,A) Sum += area(*I, *I->Next);
  111.     return abs(Sum/2, 0);
  112. }
  113.  
  114. main(){
  115.     scanf("%d", &n);
  116.     f1(i,n) { int x, y; scanf("%d%d", &x, &y); a[i]=new vertex(1.*x, 1.*y); }
  117.     for (int j=n, i=1; i<=n; j=i++) { a[j]->Next=a[i]; a[i]->Prev=a[j]; }
  118.     vertex *Root = a[1];
  119. //  show(Root);
  120.    
  121.     vector<line> T;
  122.     f2(I,Root) T.push_back(xxfd(*I, *I->Next));
  123.     f0(i,T.size()) Root=crop(T[i], Root);
  124.     cout.precision(2);
  125.     cout << fixed << area(Root) << endl;
  126. //  show(Root);
  127. }
Advertisement
Add Comment
Please, Sign In to add comment