Advertisement
blufzzz

Fivt_3/task-C/30.11.2017 (MF)

Nov 29th, 2017
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.39 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <vector>
  4. #include <cmath>
  5. #include <iterator>
  6.  
  7.  
  8. struct Point {
  9. int x;
  10. int y;
  11. int number;
  12. Point(int _x, int _y,int _number = -1):
  13. x(_x),
  14. y(_y),
  15. number(_number)
  16. {
  17. }
  18.  
  19. Point(const Point& other) {
  20. x = other.x;
  21. y = other.y;
  22. number = other.number;
  23. }
  24. bool operator==(const Point& other) const;
  25. bool operator!=(const Point& other) const;
  26. Point operator+(const Point& other) const;
  27. Point operator-(const Point& other) const;
  28. double operator^(int p) const;
  29. double operator*(const Point& other) const;
  30. double GetModule() const;
  31. void Print() const;
  32. };
  33.  
  34. Point operator-(const Point& point) {
  35. return {-point.x,-point.y};
  36. }
  37.  
  38.  
  39. bool Point::operator==(const Point &other) const{
  40. return (this->x == other.x && this->y == other.y);
  41. }
  42.  
  43.  
  44. bool Point::operator!=(const Point &other) const{
  45. return (this->x != other.x || this->y != other.y);
  46. }
  47.  
  48.  
  49. Point Point::operator+(const Point &other) const {
  50. return Point(this->x + other.x, this->y + other.y);
  51. }
  52.  
  53.  
  54. Point Point::operator-(const Point& other) const{
  55. return {this->x - other.x, this->y - other.y};
  56. }
  57.  
  58.  
  59. double Point::operator*(const Point &other) const{
  60. return (this->x*other.x + this->y*other.y);
  61. }
  62.  
  63. double Point::GetModule() const {
  64. return std::sqrt( this->x*this->x + this->y*this->y);
  65. }
  66.  
  67. void Point::Print() const {
  68. std::cout<<this->x<<' '<<this->y<<std::endl;
  69. }
  70.  
  71.  
  72. double VectorMultiplication(const Point &p1, const Point &p2) {
  73. return p1.x*p2.y - p2.x*p1.y;
  74. }
  75.  
  76. double AngleBetweenVectors( const Point& p1, const Point& p2) {
  77. double cos = (p1*p2) / (p1.GetModule()*p2.GetModule());
  78. return std::acos(cos);
  79. }
  80.  
  81.  
  82. struct Edge {
  83. Point p1;
  84. Point p2;
  85. Edge(const Point& _p1, const Point& _p2);
  86. Edge(const Edge& edge); // copy-constructor
  87. Point PivotAroundEdge(const std::vector<Point> &points);
  88. bool operator==(const Edge& other) const;
  89. };
  90.  
  91.  
  92. Edge::Edge(const Point& _p1, const Point& _p2) :
  93. p1(_p1),
  94. p2(_p2)
  95. {
  96. }
  97.  
  98.  
  99. Edge::Edge(const Edge& edge) :
  100. p1(edge.p1),
  101. p2(edge.p2)
  102. {
  103. }
  104.  
  105.  
  106. bool Edge::operator==(const Edge& other) const{
  107. return (this->p1 == other.p1 && this->p2 == other.p2 ||
  108. this->p1 == other.p2 && this->p2 == other.p1);
  109. }
  110.  
  111.  
  112. double IsRightRotation(const Point& p1, const Point& p2, const Point& p3) {
  113. Point p1p2 = p2 - p1;
  114. Point p1p3 = p3 - p1;
  115. return VectorMultiplication(p1p3, p1p2);
  116. }
  117.  
  118. bool IsIntersectionBetweenEdges(const Edge& edge1, const Edge& edge2) {
  119.  
  120. bool difference1 = (IsRightRotation(edge1.p1,edge1.p2, edge2.p1) * //true
  121. IsRightRotation(edge1.p1,edge1.p2, edge2.p2) ) <= 0;
  122.  
  123. bool difference2 = ( IsRightRotation(edge2.p1,edge2.p2, edge1.p1) * //false
  124. IsRightRotation(edge2.p1,edge2.p2, edge1.p2) ) < 0;
  125.  
  126. return difference1*difference2;
  127. }
  128.  
  129.  
  130. bool IsPointOnSegment( const Point& point1, const Point& point2, const Point& point) {
  131. // if ( point.x <= std::max(segment.p1.x, segment.p2.x) &&
  132. // point.x >= std::min(segment.p1.x, segment.p2.x) ) {
  133. // if (point.y <= std::max(segment.p1.y, segment.p2.y) &&
  134. // point.y >= std::min(segment.p1.y, segment.p2.y) ) {
  135. // return IsRightRotation(segment.p1, segment.p2 , point) == 0;
  136. // } else { return false; }
  137. // } else { return false; }
  138. Point VectorA = point - point1;
  139. Point VectorB = point - point2;
  140. return ( VectorA*VectorB + VectorA.GetModule() * VectorB.GetModule() ) == 0;
  141. }
  142.  
  143.  
  144. class ConvexPolygon {
  145. private:
  146. std::vector<Point> points;
  147. public:
  148. ConvexPolygon(const std::vector<Point>& points);
  149. void Reverse();
  150. void CounterClockOrder();
  151. std::vector<Point> GetPoints() const;
  152. void Print() const;
  153. bool BruteForce( const Point& point ) const;
  154. };
  155.  
  156.  
  157. ConvexPolygon::ConvexPolygon(const std::vector<Point>& points) :
  158. points(points)
  159. {
  160. }
  161.  
  162.  
  163. void ConvexPolygon::Reverse() {
  164. for (auto& point : points) {
  165. point.x = - point.x;
  166. point.y = - point.y;
  167. }
  168. }
  169.  
  170.  
  171. void ConvexPolygon::CounterClockOrder() {
  172. auto iterator_of_min_point = std::min_element(points.begin(), points.end(),
  173. [](const Point& p1, const Point& p2) {
  174. if (p1.y == p2.y) {
  175. return (p1.x < p2.x);
  176. } else {
  177. return (p1.y < p2.y);
  178. }
  179. });
  180. std::rotate(points.begin(), iterator_of_min_point, points.end());
  181. std::reverse(points.begin() + 1, points.end());
  182. }
  183.  
  184.  
  185. std::vector<Point> ConvexPolygon::GetPoints() const {
  186. return points;
  187. }
  188.  
  189. void ConvexPolygon::Print() const{
  190. for (const auto& point : points) {
  191. std::cout<<point.x<<' '<<point.y<<std::endl;
  192. }
  193. }
  194.  
  195.  
  196. bool DoesContainPoint(const ConvexPolygon& polygon, const Point& point) {
  197.  
  198. ///////////////
  199. //PROBLEM HERE//
  200. /////////////
  201.  
  202. std::vector<Point> points = polygon.GetPoints();
  203.  
  204. Point A = point;
  205. Point p0 = points[0];
  206. Point p1 = points[1];
  207. Point pn = points.back();
  208.  
  209. if (A == p0) {
  210. return true;
  211. }
  212. // в предположении, что порядок сохраняется
  213. if (IsRightRotation(p0, p1, A) > 0 || IsRightRotation(p0, pn, A) < 0) {
  214. return false;
  215. }
  216.  
  217. int number = points.size();
  218. int l = 1, r = number - 1;
  219. while (r - l > 1) {
  220. int q = (l + r) / 2;
  221. if (points[q] == A) {
  222. return true;
  223. }
  224. double right_rot = IsRightRotation(p0, points[q], A);
  225. if ( right_rot > 0)
  226. r = q;
  227. else
  228. l = q;
  229. }
  230. return !IsIntersectionBetweenEdges( {p0, A}, {points[l], points[r]}); // l!=r
  231. }
  232.  
  233.  
  234. double PolarAngle(const Point &p1, const Point &p2) {
  235. Point vector = p2 - p1;
  236. Point Ox (1,0);
  237. double cos = (vector*Ox) / vector.GetModule();
  238. return ( vector.y >= 0 ) ? std::acos(cos) : 2*M_PI - std::acos(cos);
  239. }
  240.  
  241.  
  242. bool ConvexPolygon::BruteForce(const Point &point) const {
  243.  
  244. double first_vm = VectorMultiplication((point - points[0]), (points[1] - points[0]));
  245. int n = points.size();
  246. bool inside = true;
  247. if (first_vm == 0) {
  248. inside = false;
  249. }
  250. for (int i = 0; i < points.size(); ++i) {
  251. if (first_vm * VectorMultiplication((point - points[i]) , (points[(i + 1) % n] - points[i])) < 0 ||
  252. VectorMultiplication((point - points[i]) , (points[(i + 1) % n] - points[i])) == 0) {
  253. inside = false;
  254. }
  255. }
  256.  
  257. bool on_the_border = false;
  258.  
  259. for (int i = 0; i < points.size(); ++i) {
  260. if ( IsPointOnSegment( points[i], points[(i + 1) % n] , point) ) {
  261. on_the_border = true;
  262. }
  263. }
  264. return (inside || on_the_border);
  265. }
  266.  
  267.  
  268.  
  269. std::vector<Point> MinkSum ( const ConvexPolygon& first, const ConvexPolygon& second ) {
  270.  
  271. int i = 0;
  272. int j = 0;
  273. std::vector<Point> V = first.GetPoints();
  274. std::vector<Point> W = second.GetPoints();
  275. std::vector<Point> answer;
  276. int n = V.size();
  277. int m = W.size();
  278. while (i < n || j < m) { // do // make borders in order to finish building
  279.  
  280. Point new_candidate = V[i%n] + W[j%m];
  281. answer.push_back(new_candidate);
  282.  
  283. double V_polar_angle = PolarAngle(V[i%n], V[(i+1)%n]);
  284. if ( i >= n ) {
  285. V_polar_angle += 2*M_PI;
  286. }
  287. double W_polar_angle = PolarAngle(W[j%m], W[(j+1)%m]);
  288. if ( j >= m ) {
  289. W_polar_angle += 2*M_PI;
  290. }
  291.  
  292. if ( V_polar_angle < W_polar_angle) {
  293. if ( i < n ) {
  294. ++i;
  295. } else {
  296. ++j;
  297. }
  298. }
  299. else if (V_polar_angle > W_polar_angle ) {
  300. if ( j < m) {
  301. ++j;
  302. } else {
  303. ++i;
  304. }
  305. }
  306. else {
  307. ++i;
  308. ++j;
  309. }
  310. }
  311. return answer;
  312. }
  313.  
  314.  
  315. //void Cases( const std::vector<Point>& V, const std::vector<Point>& W) {
  316. //
  317. // int n = V.size();
  318. // int m = W.size();
  319. //
  320. // if ( n == 1 && m == 1 ) { // PointEvent
  321. // if ( V.front() == W.front() ) {
  322. // std::cout <<"YES"<<std::endl;
  323. // } else {
  324. // std::cout <<"NO"<<std::endl;
  325. // }
  326. // exit(0);
  327. // }
  328. //
  329. // if ( n == 2 && m == 1 ) { // Point - Segment
  330. // if (IsPointOnSegment(V[0],V[1], W[0])) {
  331. // std::cout <<"YES"<<std::endl;
  332. // } else {
  333. // std::cout <<"NO"<<std::endl;
  334. // }
  335. // exit(0);
  336. // }
  337. //
  338. // if ( n == 1 && m == 2 ) { //Segment - Point
  339. // if (IsPointOnSegment(W[0],W[1], V[0])) {
  340. // std::cout <<"YES"<<std::endl;
  341. // } else {
  342. // std::cout <<"NO"<<std::endl;
  343. // }
  344. // exit(0);
  345. // }
  346. //
  347. // if ( n == 2 && m == 2 ) { //Segment - Segment
  348. // if ( IsIntersectionBetweenEdges({V[0],V[1]},{W[0],W[1]}) ) {
  349. // std::cout <<"YES"<<std::endl;
  350. // } else {
  351. // std::cout <<"NO"<<std::endl;
  352. // }
  353. // exit(0);
  354. // }
  355. //
  356. // if ( m == 1 && n > 2) {
  357. // ConvexPolygon polygon(V);
  358. // if ( DoesContainPoint(polygon, W[0]) ) {
  359. // std::cout <<"YES"<<std::endl;
  360. // } else {
  361. // std::cout <<"NO"<<std::endl;
  362. // }
  363. // exit(0);
  364. // }
  365. //
  366. // if ( n == 1 && m > 2) {
  367. // ConvexPolygon polygon(W);
  368. // if ( DoesContainPoint(polygon, V[0]) ) {
  369. // std::cout <<"YES"<<std::endl;
  370. // } else {
  371. // std::cout <<"NO"<<std::endl;
  372. // }
  373. // exit(0);
  374. // }
  375. //}
  376.  
  377.  
  378. void Input() {
  379.  
  380. std::vector<Point> V;
  381. std::vector<Point> W;
  382.  
  383. int n;
  384. std::cin>>n;
  385. for (int i = 0; i < n; ++i) {
  386. int x,y;
  387. std::cin>>x>>y;
  388. V.emplace_back(x,y,i);
  389. }
  390.  
  391. int m;
  392. std::cin>>m;
  393. for (int i = 0; i < m; ++i) {
  394. int x,y;
  395. std::cin>>x>>y;
  396. W.emplace_back(x,y,i);
  397. }
  398.  
  399. // if( n <= 2 && m <= 2) {
  400. // Cases(V,W);
  401. // return;
  402. // }
  403.  
  404. ConvexPolygon first(V);
  405. ConvexPolygon second(W);
  406.  
  407. second.Reverse();
  408. first.CounterClockOrder();
  409. second.CounterClockOrder();
  410.  
  411. ConvexPolygon MinkSumPolygon( MinkSum( first, second ) );
  412.  
  413. // std::cout<<"*********"<<std::endl;
  414. // MinkSumPolygon.Print();
  415.  
  416. Point null_point(0,0);
  417. if ( MinkSumPolygon.BruteForce(null_point)) {
  418. std::cout<<"YES"<<std::endl;
  419. } else {
  420. std::cout<<"NO"<<std::endl;
  421. }
  422. }
  423.  
  424.  
  425.  
  426. int main() {
  427.  
  428. Input();
  429.  
  430. return 0;
  431. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement