zoukankan      html  css  js  c++  java
  • UVaLive4043 UVa1411 Ants 巨人与鬼

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

    法一:暴力

    随机一个初始方案,枚举任意两条线段如果有交点就改一下。

    效率其实挺好的。

    法二:二分图最佳完美匹配

    显然没有交点的方案是所有线段的长度和最小的方案,将边权构造为欧几里德距离即可,$O(n^4)$的算法效率远不及法一,$O(n^3)$与法一持平。

     

    法三:分治

    这是紫书上介绍的方法,每次找出一个最下最左的点,将其他的点相对于这个点进行极角排序,按极角序扫描,当白点和黑点一样多时(算上最下最左那个点),将第一个点和最后一个点配对,递归处理剩下的两部分。时间复杂度大概是$O(n^2log{n})$的?效率最高。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<iostream>
     6 
     7 using namespace std;
     8 const int N = 100 + 10;
     9 
    10 #include<cmath>
    11 struct Point {
    12     int x, y;
    13     Point() {}
    14     Point(int x, int y) : x(x), y(y) {}
    15     double angle(const Point& p) const {
    16         return atan2(y - p.y, x - p.x);
    17     }
    18     bool operator < (const Point &rhs) const {
    19         return y < rhs.y || (y == rhs.y && x < rhs.x);
    20     }
    21     void read() {
    22         scanf("%d%d", &x, &y);
    23     }
    24 };
    25 
    26 int n;
    27 struct Node {
    28     Point p;
    29     int id;
    30     double ang;
    31     
    32     bool operator < (const Node &rhs) const {
    33         return ang < rhs.ang;
    34     }
    35     
    36     void getangle(const Point& p0) {
    37         ang = p.angle(p0);
    38     }
    39     
    40     int type() const {
    41         return id <= n ? 1 : -1;
    42     }
    43 }p[N * 2];
    44 
    45 int ans[N * 2];
    46 
    47 void solve(int l, int r) {
    48     if(l > r) return;
    49     int pos = l;
    50     for(int i = l + 1; i <= r; i++) {
    51         if(p[i].p < p[pos].p) pos = i;
    52     }
    53     swap(p[pos], p[l]);
    54     int cnt = p[l].type();
    55     for(int i = l + 1; i <= r; i++) {
    56         p[i].getangle(p[l].p);
    57     }
    58     sort(p + l + 1, p + r + 1);
    59     for(int i = l + 1; i <= r; i++) {
    60         cnt += p[i].type();
    61         if(!cnt) {
    62             ans[p[l].id] = p[i].id;
    63             ans[p[i].id] = p[l].id;
    64             solve(l + 1, i - 1);
    65             solve(i + 1, r);
    66             return;
    67         }
    68     }
    69 }
    70 
    71 int main() {
    72     while(scanf("%d", &n) == 1) {
    73         for(int i = 1; i <= (n << 1); i++) {
    74             p[i].p.read();
    75             p[i].id = i;
    76         }
    77         
    78         solve(1, n << 1);
    79         for(int i = 1; i <= n; i++) {
    80             printf("%d
    ", ans[i] - n);
    81         }
    82     }
    83     
    84     return 0;
    85 }
    分治算法

     

  • 相关阅读:
    简单的HelloWorld
    jsp获取绝对路径
    EasyUI validType属性
    Django meida(admin后台上传图片并可访问)
    postgresql char 与 varchar的区别
    git pull 源成分支遇到“There is no tracking information for the current branch.”错误
    Centos安装Pillow模块出错解决办法
    centos7网络配置
    表格排序插件tablesorter的初步使用介绍
    linux编译安装指定版本的python
  • 原文地址:https://www.cnblogs.com/showson/p/5197181.html
Copyright © 2011-2022 走看看