zoukankan      html  css  js  c++  java
  • 1411

    参考博客

    紫薯P230

    题意:给出平面上n个白点n个黑点,要求两两配对,且配对所连线段没有交点。

    紫薯思路:找出y坐标最小的点,如果多个,考虑x最小的。将其他点相对于这个点按极角从小到大排序,然后开始扫描,当白点和黑点一样多时(算上最下面的点),第一个和最后一个匹配,然后递归匹配中间的和外边这两部分

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <cstdio>
     6 using namespace std;
     7 const int N = 100 + 10;
     8 int n;
     9 struct Point
    10 {
    11     int x, y;
    12     Point() {}
    13     Point(int x, int y) : x(x), y(y) {}
    14     double angle(const Point& p) const // 求极角
    15     {
    16         return atan2(y - p.y, x - p.x);
    17     }
    18     bool operator< (const Point& p) const // 定义 < 
    19     {
    20         return y < p.y || (y == p.y && x < p.x);
    21     }
    22     void read() // 读入坐标
    23     {
    24         scanf("%d%d", &x, &y);
    25     }
    26 };
    27 struct Node
    28 {
    29     Point p; // 每一个点包含x,y坐标
    30     int id;
    31     double ang; // 与标准点的极角
    32     bool operator< (const Node& node) const // 定义Node的<,按极角从小到大排序
    33     {
    34         return ang < node.ang;
    35     }
    36     void getAngle(const Node& node)
    37     {
    38         ang = p.angle(node.p);
    39     }
    40     int type() // 如果是黑点(白点) 返回1,否则返回-1,判断黑点和白点数量相等时使用
    41     {
    42         return id <= n ? 1 : -1;
    43     }
    44 }p[N * 2];
    45 int ans[N * 2]; // 配对表
    46 void solve(int l, int r)
    47 {
    48     if (l > r)
    49         return;
    50     int pos = l; 
    51     for (int i = l + 1; i <= r; i++)
    52     {
    53         if (p[i].p < p[pos].p)
    54             pos = i;
    55     }
    56     swap(p[l], p[pos]); // 让怕p[l]成为最下面的点,y最小
    57     int cnt = p[l].type(); 
    58     for (int i = l + 1; i <= r; i++)  // 求出所有点与标准的极角大小
    59     {
    60         p[i].getAngle(p[l]);  
    61     }
    62     sort(p + l + 1, p + r + 1);  // 按极角从小到大排序
    63     for (int i = l + 1; i <= r; i++)
    64     {
    65         cnt += p[i].type();
    66         if (!cnt)  // 黑点和白点相等时 cnt == 0
    67         {
    68             ans[ p[i].id ] = p[l].id; // 此时的第一个 和 最后一个配对
    69             ans[ p[l].id ] = p[i].id;
    70             solve(l + 1, i - 1);  // 解决内部的
    71             solve(i + 1, r); // 解决外部的
    72             return;
    73         }
    74     }
    75 }
    76 int main()
    77 {
    78     while (scanf("%d", &n) != EOF)
    79     {
    80         for (int i = 1; i <= (n << 1); i++)
    81         {
    82             p[i].p.read();
    83             p[i].id = i;
    84         }
    85         solve(1, n << 1);
    86         for (int i = 1; i <= n; i++)
    87         {
    88             printf("%d
    ", ans[i] - n);
    89         }
    90     }
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    使用ALAssetsLibrary读取所有照片
    dispatch_after中时间的计算
    UICollectionView的header悬停
    ios侧滑返回:完美解决 interactivePopGestureRecognizer 卡住的问题
    自定义TabBar
    automaticallyAdjustsScrollViewInsets(UITextView文字顶部留有空白)
    kvo&kvc
    调用iPhone的短信
    Windows 10中Oracle数据库导出到Access数据库(MDB)
    HP Z620 Windows 7 系统安装(含磁盘阵列)
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/6271136.html
Copyright © 2011-2022 走看看