Advertisement
MystMe

RUSLAN HELP

Nov 16th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.58 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <tgmath.h>
  4. #include <algorithm>
  5. using namespace std;
  6.  
  7. const double  pi = atan(1.0) * 4.0;
  8.  
  9. // Структура, задающая одну точку
  10. struct Dot{
  11.     double x;
  12.     double y;
  13.  
  14.     Dot(double X, double Y) : x(X), y(Y) {}
  15. };
  16.  
  17. // Структура, задающая выпуклый многоугольник
  18. struct Polygon{
  19.     vector<Dot> points; // Точки граней
  20.  
  21.     void add_dot(double x, double y){
  22.         Dot tmp(x,y);
  23.         points.push_back(tmp);
  24.     }
  25. };
  26.  
  27. // Возвращает полярный угол для вектора, заданного двумя точками
  28. double polar_angle(Dot first, Dot Second){
  29.     double x = Second.x - first.x;
  30.     double y = Second.y - first.y;
  31.  
  32.     if(x > 0 && y >= 0) {
  33.         return atan(y/x);
  34.     }
  35.     if(x > 0 && y < 0) {
  36.         return atan(y/x) + 2*pi;
  37.     }
  38.     if(x < 0) {
  39.         return atan(y/x) + pi;
  40.     }
  41.     if(x == 0 && y > 0){
  42.         return pi/2;
  43.     }
  44.     if(x == 0 && y < 0){
  45.         return 3*pi/2;
  46.     }
  47. }
  48.  
  49. void cin_Polygon(Polygon& to_read, bool minus=false){
  50.     double size;
  51.     cin >> size;
  52.     int start = 0;
  53.     double min_x = 800001;
  54.     double min_y = 800001;
  55.     for(int i = 0; i < size; i++){
  56.         double x = 0;
  57.         double y = 0;
  58.  
  59.         cin >> x >> y;
  60.  
  61.         if(minus) {
  62.             x *= -1;
  63.             y *= -1;
  64.  
  65.             if(y <= min_y) {
  66.                 if(x <= min_x){
  67.                     min_x = x;
  68.                     min_y = y;
  69.                     start = i;
  70.                 }
  71.             }
  72.             to_read.add_dot(x, y);
  73.         } else {
  74.             if(y <= min_y) {
  75.                 if(x <= min_x){
  76.                     min_x = x;
  77.                     min_y = y;
  78.                     start = i;
  79.                 }
  80.             }
  81.             to_read.add_dot(x, y);
  82.         }
  83.     }
  84.  
  85.     std::rotate(to_read.points.begin(), to_read.points.begin()+start, to_read.points.end());
  86.  
  87.     size = to_read.points.size();
  88.     for(int i = 1; i < size/2; i++){
  89.         Dot tmp = to_read.points[i];
  90.         to_read.points[i] = to_read.points[size-i];
  91.         to_read.points[size-i] = tmp;
  92.     }
  93. }
  94.  
  95. // Разница Минковского:  Q - P = Q + (-P)
  96. Polygon min_diff(const Polygon& Q,const Polygon&  P){
  97.     int Q_size = Q.points.size(); // Количество точек в первом многоугольнике
  98.     int P_size = P.points.size(); // Количество точек во втором многоугольнике
  99.  
  100.     int Q_pointer = 0;  // Количество уже пройденных точек в первом
  101.     int P_pointer = 0;  // Количество уже пройденных точек во втором
  102.  
  103.     Polygon tmp;  // Многоугольник, хранящий разницу Q и P
  104.     while(Q_pointer < Q_size || P_pointer < P_size) {
  105.         double x_coor = Q.points[Q_pointer%Q_size].x + P.points[P_pointer%P_size].x;
  106.         double y_coor = Q.points[Q_pointer%Q_size].y + P.points[P_pointer%P_size].y;
  107.  
  108.         // cout << x_coor << " " << y_coor << "\n";
  109.         tmp.add_dot(x_coor, y_coor);
  110.  
  111.         double Q_angle = polar_angle(Q.points[Q_pointer%Q_size], Q.points[(Q_pointer + 1)%Q_size]);
  112.  
  113.         double P_angle = polar_angle(P.points[P_pointer%P_size], P.points[(P_pointer + 1)%P_size]);
  114.  
  115.         if (Q_angle == 0 && P_angle > pi) {
  116.             Q_angle = 2*pi;
  117.         }
  118.  
  119.         if (P_angle == 0 && Q_angle > pi) {
  120.             P_angle = 2*pi;
  121.         }
  122.  
  123.         if(Q_angle < P_angle){
  124.             Q_pointer++;
  125.         }
  126.         else if (P_angle < Q_angle){
  127.             P_pointer++;
  128.         }
  129.         else {
  130.             Q_pointer++;
  131.             P_pointer++;
  132.         }
  133.     }
  134.     return tmp;
  135. }
  136.  
  137. inline double isLeft(Dot P0, Dot P1, Dot P2 )
  138. {
  139.     return ( (P1.x - P0.x) * (P2.y - P0.y) - (P2.x -  P0.x) * (P1.y - P0.y) );
  140. }
  141.  
  142. bool Check(Polygon tmp){
  143.     Dot P2(0,0);
  144.     for(int i = 0; i < tmp.points.size()-1;i++){
  145.         double side = isLeft(tmp.points[i], tmp.points[i+1], P2);
  146.         if(side <= 0) {
  147.             return false;
  148.         }
  149.     }
  150.     return true;
  151. }
  152.  
  153. int main() {
  154.     // Считываем многоугольник Q
  155.     Polygon Q;
  156.     cin_Polygon(Q);
  157.  
  158.     // Считываем многоугольник P
  159.     Polygon P;
  160.     cin_Polygon(P, true);
  161.  
  162.     Polygon tmp = min_diff(Q,P);
  163.     Dot T = tmp.points[0];
  164.     tmp.points.push_back(T);
  165.     bool ans = Check(tmp);
  166.  
  167.     if(ans){
  168.         cout << "YES";
  169.     }
  170.     else {
  171.         cout << "NO";
  172.     }
  173.  
  174.     return 0;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement