圈水池(凸包入门)

圈水池

时间限制:3000 ms  |           内存限制:65535 KB

难度: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

题解:用到了差积的特性,如果差积为负就是顺时针转,如果为正就是逆时针,如果为0就是共线;

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 struct Node{
 8     int x,y;
 9     friend int operator < (Node a,Node b){
10         if(a.x<b.x||(a.x==b.x&&a.y<b.y))return 1;
11         else return 0;
12     }
13 };
14 int chaji(Node a,Node b,Node c){
15     return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
16 }
17 Node a[110],ans[110];
18 int main(){
19     int N,m;
20     scanf("%d",&N);
21     while(N--){
22         scanf("%d",&m);
23         for(int i=0;i<m;i++)scanf("%d%d",&a[i].x,&a[i].y);
24         sort(a,a+m);
25         int k=0;
26         for(int i=0;i<m;i++){
27             while(k>1&&chaji(ans[k-2],ans[k-1],a[i])<=0)k--;
28             ans[k++]=a[i];
29         }
30         int t=k;
31         for(int i=m-1;i>=0;i--){
32             while(k>t&&chaji(ans[k-2],ans[k-1],a[i])<=0)k--;
33             ans[k++]=a[i];
34         }
35         k--;
36         sort(ans,ans+k);
37         for(int i=0;i<k;i++)printf("%d %d\n",ans[i].x,ans[i].y);
38     }
39     return 0;
40 }
时间: 2024-08-28 12:25:56

圈水池(凸包入门)的相关文章

nyist 78 圈水池

http://acm.nyist.net/JudgeOnline/problem.php?pid=78 圈水池 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变) 输入 第一行输入的是N,代表用N组测试数据(1<=N<=10)第二行输入的是m,代表本组

NYOJ 78 圈水池( 凸包入门)

链接:click here 题目:有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变) 输出各个篱笆经过各个供水装置的坐标点,并且按照x轴坐标值从小到大输出,如果x轴坐标值相同,再安照y轴坐标值从小到大输出 样例输入 1 4 0 0 1 1 2 3 3 0 样例输出 0 0 2 3 3 0 凸包Graham模板:详细讲解:click

题解报告:NYOJ #78 圈水池(打印凸包顶点)

描述: 有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变) 输入: 第一行输入的是N,代表用N组测试数据(1<=N<=10)第二行输入的是m,代表本组测试数据共有m个供水装置(3<=m<=100)接下来m行代表的是各个供水装置的横纵坐标 输出: 输出各个篱笆经过各个供水装置的坐标点,并且按照x轴坐标值从小到大输出,如

NYOJ 78 圈水池 (入门级凸包)

题目链接:nyoj 78 题目讲解:本题考查的主要是凸包的用法,算是入门级的吧,当然前提是你接触过,平面几何: AC代码: 1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<vector> 6 using namespace std; 7 struct T 8 { 9 int x,y; 10 friend int

cogs896 圈奶牛 凸包

链接:http://cogs.pro/cogs/problem/problem.php?pid=896 题意:给出一些点,求出这些点的凸包. 几何第一题留念-- 题意已经很明白了,求出这些点的凸包.题目没有什么可以说的,这里给出两种实现方式,供读者参考. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath&g

NYOJ 圈水池

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; struct node { int x,y; }; node vex[1000];//存入的所有的点 node stackk[1000];//凸包中所有的点 int xx,yy; bool cmp1(node a,node b)

浅谈凸包之Andrew 与 Graham

前言 脑补知识点: 1.向量的内积(数量积,点乘): 公式:a· b = |a| * |b| cos<a, b>=a.x* b.y + b.x * a.y 2.向量的外积(向量积,差乘): 公式:|c|= |a|*|b|*sin<a, b> = a.x * b.y - b.x * a.y 点在多边形内判定 多边形: 就是二维平面上被一系列首尾相接.闭合的折线段围成的区域 在程序中一般用定点数组表示 其中各个定点按照逆时针顺序排序 问: 给你一个点 如何判断它是在多边形内 呢? 1.

hdu 1392 Surround the Trees (凸包)

Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7043    Accepted Submission(s): 2688 Problem Description There are a lot of trees in an area. A peasant wants to buy a rope to

HDU 1392 Surround the Trees (凸包周长)

题目链接:HDU 1392 Problem Description There are a lot of trees in an area. A peasant wants to buy a rope to surround all these trees. So at first he must know the minimal required length of the rope. However, he does not know how to calculate it. Can you