• nyoj 78-圈水池 (凸包)


    78-圈水池


    内存限制:64MB 时间限制:3000ms 特判: No
    通过数:5 提交数:6 难度:4

    题目描述:

    有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变)

    输入描述:

    第一行输入的是N,代表用N组测试数据(1<=N<=10)
    第二行输入的是m,代表本组测试数据共有m个供水装置(3<=m<=100)
    接下来m行代表的是各个供水装置的横纵坐标

    输出描述:

    输出各个篱笆经过各个供水装置的坐标点,并且按照x轴坐标值从小到大输出,如果x轴坐标值相同,再安照y轴坐标值从小到大输出

    样例输入:

    1
    4
    0 0
    1 1
    2 3
    3 0
    

    样例输出:

    0 0
    2 3
    3 0

    分析:
      1、凸包裸题
      2、说明,凸包问题可以用来求一个块区域的最值问题
      3、上凸包 + 下凸包 ==> 最短的篱笆

    核心代码:
     1 int cnt = 0;
     2 for(int i = 0; i < n; ++ i) // 下凸包
     3 {
     4     while(cnt > 1 && cross_product(ans[cnt-2], ans[cnt-1], P[i]) <= 0)
     5         -- cnt;
     6     ans[cnt ++] = P[i];
     7 }
     8 int temp = cnt;
     9 for(int i = n-1; i >= 0; -- i)
    10 {
    11     while(cnt > temp && cross_product(ans[cnt-2], ans[cnt-1], P[i]) <= 0)
    12         -- cnt;
    13     ans[cnt ++] = P[i];
    14 }
    15 -- cnt;

    C/C++代码实现(AC):

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <stack>
     7 #include <map>
     8 #include <queue>
     9 #include <set>
    10 
    11 using namespace std;
    12 const int MAXN = 105;
    13 struct node
    14 {
    15     int x, y;
    16 }P[MAXN], ans[MAXN];
    17 
    18 bool cmp(node a, node b)
    19 {
    20     if (a.x != b.x) return a.x < b.x;
    21     return a.y < b.y;
    22 }
    23 
    24 int cross_product(node a, node b, node c)
    25 {
    26     return ((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
    27 }
    28 
    29 int main()
    30 {
    31     int N;
    32     scanf("%d", &N);
    33     while(N --)
    34     {
    35         int n, cnt = 0;
    36         scanf("%d", &n);
    37         for (int i = 0; i < n; ++ i)
    38             scanf("%d%d", &P[i].x, &P[i].y);
    39 
    40         sort (P, P+n, cmp);
    41         for(int i = 0; i < n; ++ i) // 下凸包
    42         {
    43             while(cnt > 1 && cross_product(ans[cnt-2], ans[cnt-1], P[i]) <= 0)
    44                 -- cnt;
    45             ans[cnt ++] = P[i];
    46         }
    47         int temp = cnt;
    48         for(int i = n-1; i >= 0; -- i) // 上凸包
    49         {
    50             while(cnt > temp && cross_product(ans[cnt-2], ans[cnt-1],P[i]) <= 0)
    51                 -- cnt;
    52             ans[cnt ++] = P[i];
    53         }
    54         -- cnt;
    55         sort (ans, ans + cnt, cmp);
    56         for (int i = 0; i < cnt; ++ i)
    57             printf("%d %d
    ", ans[i].x, ans[i].y);
    58     }
    59     return 0;
    60 }
  • 相关阅读:
    python基础之元组、文件操作、编码、函数、变量
    python---基础之模块,列表,元组,字典
    python成长之路-----day1-----作业(登录程序和三级菜单)
    k8s的port、targetport、nodeport之间的区别
    查找并删除文件
    systemctl自定义service
    中标麒麟7.0源
    springboot问题,没有主清单属性
    iso搭建本地源
    添加路由
  • 原文地址:https://www.cnblogs.com/GetcharZp/p/9113116.html
Copyright © 2020-2023  润新知