• nyoj #78 圈水池(打印凸包顶点)


    描述:

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

    输入:

    第一行输入的是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

    解题思路:题意说得很清楚,按规则输出凸包上所有的顶点坐标。这里用Andrew算法,注意必须构造完整的凸包,即构造凸包上侧时要将起点包括进去(必须i>=0不能i>0),最后舍去一个多余的起点再排序输出即可。

    AC代码(0ms):

     1 #include<iostream>
     2 #include<string.h>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<cmath>
     6 using namespace std;
     7 const int maxn=105;
     8 struct node{int x,y;}vex[maxn],stackk[maxn];
     9 bool cmp(node a,node b){//找基点
    10     return ((a.y<b.y)||(a.y==b.y&&a.x<b.x));
    11 }
    12 bool cmp1(node a,node b){
    13     return ((a.x<b.x)||(a.x==b.x&&a.y<b.y));
    14 }
    15 int cross(node p0,node p1,node p2){
    16     return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    17 }
    18 int main(){
    19     int t,n;
    20     while(~scanf("%d",&t)){
    21         while(t--){
    22             scanf("%d",&n);
    23             for(int i=0;i<n;++i)
    24                 scanf("%d%d",&vex[i].x,&vex[i].y);
    25             memset(stackk,0,sizeof(stackk));
    26             sort(vex,vex+n,cmp);
    27             int top=-1;
    28             for(int i=0;i<n;++i){//构造凸包下侧
    29                 while(top>0&&cross(stackk[top-1],stackk[top],vex[i])<=0)top--;
    30                 stackk[++top]=vex[i];
    31             }
    32             for(int i=n-2,k=top;i>=0;--i){//构造凸包上侧,要构造完整的凸包(i>=0),最后一个坐标点即起点舍去即可
    33                 while(top>k&&cross(stackk[top-1],stackk[top],vex[i])<=0)top--;
    34                 stackk[++top]=vex[i];
    35             }
    36             sort(stackk,stackk+top,cmp1);//舍弃最后一个多余的起点坐标
    37             for(int i=0;i<top;++i)
    38                 printf("%d %d
    ",stackk[i].x,stackk[i].y);
    39         }
    40     }
    41     return 0;
    42 }
  • 相关阅读:
    反向映射和写时复制
    内存分析的好blog
    minicom使用
    tee的妙用
    网络带宽
    mem analyse
    linux 应用层常用API/命令
    ubuntu 库依赖问题
    Python基础学习笔记(一:hello world)
    第7章 取消与关闭
  • 原文地址:https://www.cnblogs.com/acgoto/p/9552160.html
Copyright © 2020-2023  润新知