1011. Cut Rectangles (35)解题报告

来源:互联网 发布:图160和b1b数据对比 编辑:程序博客网 时间:2024/06/06 07:17

原题链接:

1011. Cut Rectangles (35)


解题思路:

长方形切割有三种情况,下面分情况讨论:

  1. 两个直角三角形。这两个三角形斜边相等,另外两边两两相等,而且四个锐角可以相应组成两个直角。
  2. 一个直角三角形,一个直角梯形。斜边相等,且可以组成长方形。
  3. 一个直角三角形和一个五边形。斜边相等,且可以组成长方形。
约束条件:
直角三角形、直角梯形、五边形的直角边与坐标轴成0、45、90、135或180度。


通过画面:



代码:
#define _CRT_SECURE_NO_WARNINGS#include <cstdio>#include <cstdlib>#include <cassert>#include <cmath>#include <vector>#include <algorithm>using namespace std;struct point {  double x, y;  point(const double x = 0.0, const double y = 0.0) : x(x), y(y) {}  point operator-(point p2)  {    return point(x - p2.x, y - p2.y);  }};bool judge(vector<point>& shape1, vector<point>& shape2);double length(point p1, point p2);double angle(point p1, point p2, point p3);int dcmp(double d1, double d2);bool leftHand(point p1, point p2, point p3);const double pi = acos(-1);const double delta = 1e-5;int main(){  int n = 0, k1 = 0, k2 = 0;  assert(1 == scanf("%d", &n));  for (int i = 0; i < n; i++) {    assert(1 == scanf("%d", &k1));    vector<point> shape1, shape2;    for (int i = 0; i < k1; i++) {      point tmp;      assert(scanf("%lf %lf", &tmp.x, &tmp.y) == 2);      shape1.push_back(tmp);    }    if (!leftHand(shape1[0], shape1[1], shape1[2])) {      reverse(shape1.begin(), shape1.end());    }    assert(scanf("%d", &k2) == 1);    for (int i = 0; i < k2; i++) {      point tmp;      assert(2 == scanf("%lf %lf", &tmp.x, &tmp.y));      shape2.push_back(tmp);    }    if (!leftHand(shape2[0], shape2[1], shape2[2])) {      reverse(shape2.begin(), shape2.end());    }    if (judge(shape1, shape2)) {      puts("YES");    }    else {      puts("NO");    }  }  return 0;}bool judge(vector<point>& shape1, vector<point>& shape2){  if (shape1.size() < 3 || shape2.size() < 3 || shape1.size() > 5 || shape2.size() > 5){    return false;  }  else if (shape1.size() + shape2.size() > 8) {    return false;  }  else {    if (shape1.size() > shape2.size()) {      swap(shape1, shape2);    }    vector<double> angle1, angle2, segment1, segment2;    for (int i = 0; i < (int)shape1.size(); i++) {      segment1.push_back(length(shape1[(i - 1 + shape1.size()) % shape1.size()], shape1[i]));      angle1.push_back(angle(shape1[(i - 1 + shape1.size()) % shape1.size()], shape1[i], shape1[(i + 1) % shape1.size()]));    }    for (int i = 0; i < (int)shape2.size(); i++) {      segment2.push_back(length(shape2[(i - 1 + shape2.size()) % shape2.size()], shape2[i]));      angle2.push_back(angle(shape2[(i - 1 + shape2.size()) % shape2.size()], shape2[i], shape2[(i + 1) % shape2.size()]));    }    if (shape1.size() == 4 && shape2.size() == 4) {      bool flag = true;      for (int i = 0; i < 4 && flag; i++) {        for (int j = 0; j < 4 && flag; j++) {          if (dcmp(segment1[i], segment2[j]) == 0) {            bool flag2 = true;            if (!((dcmp(angle1[(i - 1 + 4) % 4] + angle2[j], pi) == 0 && dcmp(angle1[i] + angle2[(j - 1 + 4) % 4], pi) == 0) ||               (dcmp(angle1[i] + angle2[j], pi) == 0 && dcmp(angle1[(i - 1 + 4) % 4] + angle2[(j - 1 + 4) % 4], pi) == 0))) {              flag2 = false;            }            if (dcmp(angle1[(i + 1) % 4], pi / 2) || dcmp(angle2[(j + 1) % 4], pi / 2)) {              flag2 = false;            }            if (dcmp(angle1[(i + 2) % 4], pi / 2) || dcmp(angle2[(j + 2) % 4], pi / 2)) {              flag2 = false;            }            if (flag2) {              double res1 = angle(shape1[(i + 1) % 4] - shape1[(i + 2) % 4], point(0, 0), point(0, 1));              double res2 = angle(shape2[(j + 1) % 4] - shape2[(j + 2) % 4], point(0, 0), point(0, 1));              if (!((dcmp(res1, pi / 2) == 0 || dcmp(res1, 0) == 0 || dcmp(res1, pi) == 0 || dcmp(res1, pi / 2 * 3) == 0)                && (dcmp(res2, pi / 2) == 0 || dcmp(res2, 0) == 0 || dcmp(res2, pi) == 0 || dcmp(res2, pi / 2 * 3) == 0))) {                flag2 = !flag2;              }            }            flag = !flag2;          }        }      }      return !flag;    } // if 4 4    else if (shape1.size() == 3 && shape2.size() == 3) {      bool flag = true;      for (int i = 0; i < 3 && flag; i++) {        for (int j = 0; j < 3 && flag; j++) {          if (dcmp(segment1[i], segment2[j]) == 0) {            bool flag2 = true;            if (!((dcmp(segment1[(i + 1) % 3], segment2[(j - 1 + 3) % 3]) == 0 && dcmp(segment1[(i - 1 + 3) % 3], segment2[(j + 1) % 3]) == 0) ||              (dcmp(segment1[(i - 1 + 3) % 3], segment2[(j - 1 + 3) % 3]) == 0 && dcmp(segment1[(i + 1) % 3], segment2[(j + 1) % 3]) == 0))) {              flag2 = false;            }            if (dcmp(angle1[(i + 1) % 3], pi / 2) != 0) {              flag2 = false;            }            if (flag2) {              double res1 = angle(shape1[(i + 1) % 3] - shape1[(i + 2) % 3], point(0, 0), point(0, 1));              double res2 = angle(shape2[(j + 1) % 3] - shape2[(j + 2) % 3], point(0, 0), point(0, 1));              if (!((dcmp(res1, pi / 2) == 0 || dcmp(res1, 0) == 0 || dcmp(res1, pi) == 0 || dcmp(res1, pi / 2 * 3) == 0)                && (dcmp(res2, pi / 2) == 0 || dcmp(res2, 0) == 0 || dcmp(res2, pi) == 0 || dcmp(res2, pi / 2 * 3) == 0))) {                flag2 = !flag2;              }            }            flag = !flag2;                    }        }      }      return !flag;    } // if 3 3    else if (shape1.size() == 3 && shape2.size() == 4 || shape1.size() == 4 && shape2.size() == 3) {      bool flag = true;      for (int i = 0; i < 3 && flag; i++) {        for (int j = 0; j < 4 && flag; j++) {          if (dcmp(segment1[i], segment2[j]) == 0) {            bool flag2 = true;            if (!(dcmp(angle1[i] + angle2[(j - 1 + 4) % 4], pi / 2) == 0 && dcmp(angle1[(i - 1 + 3) % 3] + angle2[j], pi) == 0) &&               !(dcmp(angle1[i] + angle2[(j - 1 + 4) % 4], pi ) == 0 && dcmp(angle1[(i - 1 + 3) %3] + angle2[j], pi / 2) == 0)) {              flag2 = false;            }            if (dcmp(angle1[(i + 1) % 3], pi / 2) != 0 || dcmp(angle2[(j + 1) % 4], pi / 2) != 0 || dcmp(angle2[(j + 2) % 4], pi / 2) != 0) {              flag2 = false;            }            if (flag2) {              double res1 = angle(shape1[(i + 1) % 3] - shape1[(i + 2) % 3], point(0, 0), point(0, 1));              double res2 = angle(shape2[(j + 1) % 4] - shape2[(j + 2) % 4], point(0, 0), point(0, 1));              if (!((dcmp(res1, pi / 2) == 0 || dcmp(res1, 0) == 0 || dcmp(res1, pi) == 0 || dcmp(res1, pi / 2 * 3) == 0)                && (dcmp(res2, pi / 2) == 0 || dcmp(res2, 0) == 0 || dcmp(res2, pi) == 0 || dcmp(res2, pi / 2 * 3) == 0))) {                flag2 = !flag2;              }            }            flag = !flag2;          }        }      } // outer for      return !flag;    } // if 3 4    else {      bool flag = true;      for (int i = 0; i < 3 && flag; i++) {        for (int j = 0; j < 5 && flag; j++) {          if (dcmp(segment1[i], segment2[j]) == 0) {            bool flag2 = true;            if (!((dcmp(angle1[i] + angle2[(j - 1 + 5) % 5], pi) == 0 && dcmp(angle1[(i - 1 + 3) % 3] + angle2[j], pi) == 0) ||               (dcmp(angle1[i] + angle2[j], pi) == 0 && dcmp(angle1[(i - 1 + 3) % 3] + angle2[(j - 1 + 5) % 5], pi) == 0))) {              flag2 = false;            }            if (dcmp(angle1[(i + 1) % 3], pi / 2) != 0 || dcmp(angle2[(j + 1) % 5], pi / 2) != 0 || dcmp(angle2[(j + 2) % 5], pi / 2) != 0) {              flag2 = false;            }            if (flag2) {              double res1 = angle(shape1[(i + 1) % 3] - shape1[(i + 2) % 3], point(0, 0), point(0, 1));              double res2 = angle(shape2[(j + 1) % 5] - shape2[(j + 2) % 5], point(0, 0), point(0, 1));              if (!((dcmp(res1, pi / 2) == 0 || dcmp(res1, 0) == 0 || dcmp(res1, pi) == 0 || dcmp(res1, pi / 2 * 3) == 0)                && (dcmp(res2, pi / 2) == 0 || dcmp(res2, 0) == 0 || dcmp(res2, pi) == 0 || dcmp(res2, pi / 2 * 3) == 0))) {                flag2 = !flag2;              }            }            flag = !flag2;          }        }      }      return !flag;    }// if 3 5  }}double length(point p1, point p2){  double x = p1.x - p2.x;  double y = p1.y - p2.y;  return sqrt(x * x + y * y);}double angle(point p1, point p2, point p3){  point v1 = p1 - p2;  point v2 = p3 - p2;  return acos((v1.x * v2.x + v1.y * v2.y) / (length(p1, p2) * length(p2, p3)));}int dcmp(double d1, double d2){  if (fabs(d1 - d2) < delta) {    return 0;  }  else if (d1 > d2) {    return 1;  }  else {    return -1;  }}bool leftHand(point p1, point p2, point p3){  return p1.x * p2.y - p1.y * p2.x + p2.x * p3.y - p2.y * p3.x + p3.x * p1.y - p3.y * p1.x > 0;}


原创粉丝点击