Guest User

AllSib2011-Planetarium-Kuzkokov-Solution-155K

a guest
Nov 7th, 2011
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.11 KB | None | 0 0
  1. Просмотр исходного кода
  2. Задача: Планетарий
  3. Время: 16:26:57 7-11-11
  4. Язык: MinGW C++ (GCC 4.6.1)
  5.  
  6. #define _USE_MATH_DEFINES
  7. #include <cmath>
  8. #include <cstdio>
  9. #include <vector>
  10. #include <algorithm>
  11.  
  12. #define EPS 1e-6
  13. #define GRID 15
  14. #define BRIGHTEST 100
  15.  
  16. using namespace std;
  17.  
  18. struct point {
  19.     double x;
  20.     double y;
  21.     double z;
  22.     point() : x(0), y(0), z(0) { }
  23.     point& operator-=(const point& b) {
  24.         x-=b.x; y-=b.y; z-=b.z;
  25.         return *this;
  26.     }
  27.     point& operator+=(const point& b) {
  28.         x+=b.x; y+=b.y; z+=b.z;
  29.         return *this;
  30.     }
  31.     double operator!() const {
  32.         return x*x+y*y+z*z;
  33.     }
  34.     point& operator*=(const double& b) {
  35.         x*=b; y*=b; z*=b;
  36.         return *this;
  37.     }
  38.     point operator^(const point& b) const {
  39.         point res;
  40.         res.x = y*b.z - z*b.y;
  41.         res.y = z*b.x - x*b.z;
  42.         res.z = x*b.y - y*b.x;
  43.         return res;
  44.     }
  45.     double operator*(const point& b) const {
  46.         return x*b.x+y*b.y+z*b.z;
  47.     }
  48. };
  49.  
  50. struct point2d {
  51.     double x;
  52.     double y;
  53.     point2d() : x(0), y(0) { }
  54.     double operator!() const {
  55.         return x*x+y*y;
  56.     }
  57.     point2d& operator*=(double b) {
  58.         x*=b; y*=b;
  59.         return *this;
  60.     }
  61.     point2d& operator+=(const point2d& b) {
  62.         x+=b.x; y+=b.y;
  63.         return *this;
  64.     }
  65.     point2d& operator-=(const point2d& b) {
  66.         x-=b.x; y-=b.y;
  67.         return *this;
  68.     }
  69.     bool operator< (const point2d& b) const {
  70.         return (int)(GRID*x)==(int)(GRID*b.x) ? (int)(GRID*y)<(int)(GRID*b.y) : (int)(GRID*x)<(int)(GRID*b.x);
  71.     }
  72.     bool operator== (const point2d& b) const {
  73.         return (int)(GRID*x)==(int)(GRID*b.x) && (int)(GRID*y)==(int)(GRID*b.y);
  74.     }
  75. };
  76.  
  77. struct star : point {
  78.     double l;
  79.     void read() {
  80.         scanf("%lf%lf%lf%lf",&x,&y,&z,&l);
  81.     }
  82.     void normalize(const star& home) {
  83.         *this -= home;
  84.         double coef=1/!*this;
  85.         *this *= sqrt(coef);
  86.         l *= coef;
  87.     }
  88.     bool operator< (const star& b) const {
  89.         return l > b.l;
  90.     }
  91. };
  92.  
  93. vector<star> tenture;
  94.  
  95. struct asterism : vector<point2d> {
  96.     int vis;
  97.     void read() {
  98.         char str[256];
  99.         gets(str);
  100.                 char* t=str;
  101.         while(1) {
  102.             char* s=t;
  103.             double x = strtol(t,&t,10)-50;
  104.             if (t==s) break;
  105.             push_back(point2d());
  106.             point2d& pt = *rbegin();
  107.             pt.x = x;
  108.             pt.y = strtol(t,&t,10)-50;
  109.         }
  110.         normalize();
  111.     }
  112.     void normalize() {
  113.         double scale=0;
  114.         point2d farthest;
  115.         for(iterator it=begin();it!=end();++it) {
  116.             double r2 = !*it;
  117.             if (scale < r2) {
  118.                 scale = r2;
  119.                 farthest = *it;
  120.             }
  121.         }
  122.         scale = 1/scale;
  123.         for(iterator it=begin();it!=end();++it) {  
  124.             point2d res;
  125.             res.x = it->x*farthest.x + it->y*farthest.y;
  126.             res.y = it->y*farthest.x - it->x*farthest.y;
  127.             res *= scale;
  128.             *it = res;
  129.         }
  130.         sort(begin(),end());
  131.     }
  132.     bool operator==(const asterism& b) {
  133.         //TODO optimize
  134.         if (size() != b.size()) return false;
  135.         vector<bool> marked;
  136.         marked.resize(size());
  137.         for(int i=0;i<size();i++) {
  138.             point2d tmp = (*this)[i];
  139.             tmp.x -= .5/GRID; tmp.y -= .5/GRID;
  140.             int s = lower_bound(b.begin(),b.end(),tmp)-b.begin();
  141.             while (s<size() && marked[s]) s++;
  142.             if (tmp == b[s]) { marked[s]=true; continue; }
  143.             tmp.x += 1./GRID;
  144.             s = lower_bound(b.begin(),b.end(),tmp)-b.begin();
  145.             while (s<size() && marked[s]) s++;
  146.             if (tmp == b[s]) { marked[s]=true; continue; }
  147.             tmp.x -= 1./GRID; tmp.y += 1./GRID;
  148.             s = lower_bound(b.begin(),b.end(),tmp)-b.begin();
  149.             while (s<size() && marked[s]) s++;
  150.             if (tmp == b[s]) { marked[s]=true; continue; }
  151.             tmp.x += 1./GRID;
  152.             s = lower_bound(b.begin(),b.end(),tmp)-b.begin();
  153.             while (s<size() && marked[s]) s++;
  154.             if (tmp == b[s]) { marked[s]=true; continue; }
  155.             return false;
  156.         }
  157.         return true;
  158.     }
  159. };
  160.  
  161. vector<asterism> asts;
  162.  
  163. void init() {
  164.     freopen("input.txt","rt",stdin);
  165.     freopen("output.txt","wt",stdout);
  166.     int n;
  167.     scanf("%d",&n);
  168.     for(int i=0;i<n;i++) {
  169.         tenture.push_back(star());
  170.         tenture.rbegin()->read();
  171.     }
  172.     int astn;
  173.     int vis=1;
  174.     while(scanf("%d\n",&astn) == 1) {
  175.         for(int i=0;i<astn;i++) {
  176.             asts.push_back(asterism());
  177.             asterism& ast = *asts.rbegin();
  178.             ast.read();
  179.             ast.vis = vis;
  180.         }
  181.         vis++;
  182.     }
  183. }
  184.  
  185. struct celestialSphere : vector<star> {
  186.     int homei;
  187.     void normalize(const star& home) {
  188.         for(int i=0;i<size();i++) {
  189.             if (i==homei-1) {
  190.                 (*this)[i]=*rbegin();
  191.                 pop_back();
  192.             }
  193.             (*this)[i].normalize(home);
  194.         }
  195.         sort(begin(), end());
  196.         }
  197.  
  198.     void findCloseStars(vector<star>& res,const star& anchor) {
  199.         //TODO optimize
  200.         double next=0;
  201.         for(iterator it=begin(); it!=end(); ++it) {
  202.             if (anchor*(*it) > cos(M_PI/18)) {
  203.                 if (it->l < next) break;
  204.                 next=0.2*it->l;
  205.                 res.push_back(*it);
  206.                 if (res.size() > 11) break;
  207.             }
  208.         }
  209.     }
  210.  
  211.     void tryAsterism(const star& anchor) {
  212.         vector<star> close;
  213.         findCloseStars(close,anchor);
  214.         if (close.size()<4 || close.size() > 10) return;
  215.         point xx;
  216.         for(vector<star>::iterator it=close.begin();it!=close.end();++it)
  217.             xx += *it;
  218.         xx *= 1/sqrt(!xx);
  219.         point yy;
  220.         yy.x = 1; yy.y = 0; yy.z = 0;
  221.         yy = yy ^ xx;
  222.         if (!yy < EPS) {
  223.             yy.x = 0; yy.y = 1; yy.z = 0;
  224.             yy = yy ^ xx;
  225.         }
  226.         point zz = xx^yy;
  227.         asts.push_back(asterism());
  228.         asterism& ast = *asts.rbegin();
  229.         ast.vis = -homei;
  230.         for(vector<star>::iterator it=close.begin();it!=close.end();++it) {
  231.             ast.push_back(point2d());
  232.             point2d& img = *ast.rbegin();
  233.             img.x = zz*(*it);
  234.             img.y = yy*(*it);
  235.             img *= 1/(xx*(*it));
  236.         }
  237.         ast.normalize();
  238.     }
  239. };
  240.  
  241. void findAsterisms(int homei) {
  242.     const star& home=tenture[homei];
  243.     if (home.l>4) return;
  244.     celestialSphere sphere;
  245.     sphere.insert(sphere.begin(),tenture.begin(),tenture.end());
  246.     sphere.homei = homei+1;
  247.     sphere.normalize(home);
  248.     for(int i=0;i<BRIGHTEST;i++) sphere.tryAsterism(sphere[i]);
  249. }
  250.  
  251. int found[10100];
  252. void examineSkies() {
  253.     int vn = asts.rbegin()->vis;
  254.     for(int i=0;i<tenture.size();i++) findAsterisms(i);
  255.     //TODO optimize
  256.     for(int i=0;i<asts.size();i++) {
  257.         if (found[asts[i].vis]) continue;
  258.         if (asts[i].vis<0) break;
  259.         for(int j=asts.size()-1;j>=0;j--) {
  260.             if (asts[j].vis>0) break;
  261.             if (asts[i]==asts[j]) {
  262.                 found[asts[i].vis]=-asts[j].vis;
  263.                 break;
  264.             }
  265.         }
  266.     }
  267.     for(int i=1;i<=vn;i++) printf("%d\n",found[i]);
  268. }
  269.  
  270. int main() {
  271.     init();
  272.     examineSkies();
  273.     return 0;
  274. }
  275.  
Advertisement
Add Comment
Please, Sign In to add comment