圈水池 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 该题可用于凸包算法入门 可查看链接:http://www.cnblogs.com/dream-it-possible/p/8514706.html/*
author:谦智
圈水池 nyoj 78 凸包算法
*/ //Graham扫描法 求解凸包问题
#include<iostream>
#include<algorithm>
using namespace std;
const int N = ;
struct Node{
int x,y;
Node() {}
Node(int x,int y) {
this->x = x;
this->y = y;
}
};
Node st[N];
struct cmp{//将所有的点坐标按照x从小到大排序 x相等时按照y从小到大排序
bool operator()(const Node& a,const Node& b) {
if (a.x != b.x) return a.x < b.x;
return a.y < b.y;
}
};
int cross(Node a,Node b,Node c) { //求向量ab和向量ac的叉积 如果结果为正则ab向量转到ac向量上通过逆时针(转的角度为小角) ==》c点在ab的左侧 ==》c相对于 a 的幅角 α 大于 b相对于 a 的幅角 α
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
long long dist(Node a,Node b) {//计算两点之间的距离的平方 用于比较故不用求出实际的距离
return (b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y);
}
bool cmp1(const Node& a,const Node& b) {// 相对于 st[0] 的幅角 α从小到大排序
int m = cross(st[],a,b);
if (m > ) return ;
if (m == && dist(st[],a) <= dist(st[],a)) return ;
return ;
}
int main() {
int t;
cin >> t;
Node node[];
while (t--) {
int n;
cin >> n;
for (int i = ; i < n; i++) {
cin >> node[i].x >> node[i].y;
}
sort(node,node+n,cmp());
int x1,y1,x2,y2;
st[] = node[];
sort(node+,node+n,cmp1);
st[] = node[];
int top = ;
for (int i = ; i < n; i++) {
while (top > && cross(st[top-],st[top],node[i]) < ) {
top--;
}
st[++top] = node[i];
}
sort(st,st+top+,cmp());
for (int i = ; i <= top; i++) {
cout << st[i].x << " "<< st[i].y << endl;
}
}
} //用递归算法求出凸包问题 wa
//#include<iostream>
//#include<algorithm>
//using namespace std;
//struct Node{
// int x,y;
// Node() {}
// Node(int x,int y) {
// this->x = x;
// this->y = y;
// }
//};
//struct cmp{
// bool operator()(const Node& a,const Node& b) {
// if (a.x != b.x) return a.x < b.x;
// return a.y < b.y;
// }
//};
//int cut;
//Node ans[105];
//void getAnsArr(Node node[],int n,int x1,int y1,int x2,int y2) ;
//int main() {
// int t;
// cin >> t;
// Node node[105];
// while (t--) {
// int n;
// cin >> n;
// for (int i = 0; i < n; i++) {
// cin >> node[i].x >> node[i].y;
// }
// sort(node,node+n,cmp());
// int x1,y1, x2,y2;
// x1 = node[0].x;
// y1 = node[0].y;
// x2 = node[n-1].x;
// y2 = node[n-1].y;
// ans[0] = Node(x1,y1);
// ans[1] = Node(x2,y2);
// cut = 2;
// getAnsArr(node,n,x1,y1,x2,y2);
// sort(ans,ans+cut,cmp());
// for (int i = 0; i < cut; i++) {
// cout << ans[i].x << " " << ans[i].y << endl;
// }
// }
//}
//void getAnsArr(Node node[],int n,int x1,int y1,int x2,int y2) {
// int x3,y3, count = 0;
// if (n <= 1) return ;
// x3 = node[0].x;
// y3 = node[0].y;
// Node temp[105];
// int l = x1*y2+x3*y1+x2*y3-x3*y2-x2*y1-x1*y3;
// int lMax = l;
// int k = 0;
// for (int i = 1; i < n; i++) {
// x3 = node[i].x;
// y3 = node[i].y;
// l = x1*y2+x3*y1+x2*y3-x3*y2-x2*y1-x1*y3;
// if (l >= 0) {
// temp[count++] = node[i];
// }
// if (l > lMax) {
// lMax = l;
// k = i;
// }
// }
// if (lMax <= 0) {
// for (int i = 0; i < count; i++) {
// x3 = temp[i].x;
// y3 = temp[i].y;
// l = x1*y2+x3*y1+x2*y3-x3*y2-x2*y1-x1*y3;
// if (l == 0 && !((x3==x2&&y3==y2)||(x3==x1&&y3==y1)) ) {
// ans[cut++] = temp[i];
// }
// }
// return ;
// } else {
// ans[cut++] = node[k];
// if (count == 0) return ;
// }
// getAnsArr(temp,count,x1,y1,node[k].x,node[k].y);
// getAnsArr(temp,count,node[k].x,node[k].y,x2,y2);
//}
圈水池 nyoj 78 凸包算法的更多相关文章
- NYOJ 78 圈水池 (入门级凸包)
题目链接:nyoj 78 单调链凸包小结 题目讲解:本题考查的主要是凸包的用法,算是入门级的吧,当然前提是你接触过,平面几何: AC代码: #include<iostream> #inc ...
- 题解报告:NYOJ #78 圈水池(打印凸包顶点)
描述: 有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!( ...
- nyist 78 圈水池
http://acm.nyist.net/JudgeOnline/problem.php?pid=78 圈水池 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 有一个 ...
- NYOJ-78 圈水池,凸包裸模板!
圈水池 时间限制:3000 ms | 内存限制:65535 KB 难度:4 刚做完HDU1392,就看到这个题,嗯,原代码改改就过了. 题意不多说了,会凸包的话很简单,不会也不难,这道题时限是4s ...
- openlayer的凸包算法实现
最近在要实现一个openlayer的凸多边形,也遇到了不小的坑,就记录一下 1.具体的需求: 通过在界面点击,获取点击是的坐标点,来绘制一个凸多边形. 2.思考过程: 1)首先,我们得先获取点击事件发 ...
- Graham Scan凸包算法
获得凸包的算法可以算是计算几何中最基础的算法之一了.寻找凸包的算法有很多种,Graham Scan算法是一种十分简单高效的二维凸包算法,能够在O(nlogn)的时间内找到凸包. 首先介绍一下二维向量的 ...
- 计算几何-凸包算法 Python实现与Matlab动画演示
凸包算法是计算几何中的最经典问题之一了.给定一个点集,计算其凸包.凸包是什么就不罗嗦了 本文给出了<计算几何——算法与应用>中一书所列凸包算法的Python实现和Matlab实现,并给出了 ...
- nyoj 78:圈水池 【凸包入门】
题目链接 将所有点按从左至右顺序排序,然后将所有点先从左到右扫描再从右到左扫描,逐渐将凸包轮廓“勾勒”出来 (凸包轮廓满足,轮廓上连续的三个点按先后顺序给出的话呈逆时针方向) 最后删去一个重复的起(终 ...
- nyoj_78:圈水池(凸包入门)
题目链接 将所有点按从左至右顺序排序,然后将所有点先从左到右扫描再从右到左扫描,逐渐将凸包轮廓"勾勒"出来 (凸包轮廓满足,轮廓上连续的三个点按先后顺序给出的话呈逆时针方向) 最后 ...
随机推荐
- Python Scrapy反爬虫常见解决方案(包含5种方法)
爬虫的本质就是“抓取”第二方网站中有价值的数据,因此,每个网站都会或多或少地采用一些反爬虫技术来防范爬虫.比如前面介绍的通过 User-Agent 请求头验证是否为浏览器.使用 JavaScript ...
- centos7之zabbix的监控H3C ER3200G2流量
1.首先在服务器端安装snmp工具 yum -y install net-snmp-utils snmp-libs snmp-devel snmp 启动snmpd服务 systemctl start ...
- AWS Step Function Serverless Applications
Installing VS Components To follow along with this article, you must have an AWS account and install ...
- ZYNQ原理图中添加RTL设计模块
前言 已有的RTL模块怎么添加到原理图中? 流程 (1)添加文件到设计中. (2)右键文件添加到block design中. (3)连线即可. 以上.
- 深入理解JVM(7)——线程安全和锁优化
Java中的线程安全 按照线程安全的“安全程度”由强至弱来排序,可以将Java语中各种操作共享的数据分为以下5类:不可变. 绝对线程安全. 相对线程安全. 线程兼容和线程对立. 1.不可变 不变的对象 ...
- 初入 nodejs -遍历文件夹
//操作文件 /* 1.fs.stat 获取文件状态 2.fs.readdir 读取文件夹数据 3.fs.access 判断文件夹是否存在 4.path.join 拼路径 */ //操作文件 cons ...
- Java基础 -- 字符串(格式化输出、正则表达式)
一 字符串 1.不可变String String对象是不可变的,查看JDK文档你就会发现,String类中每一个看起来会修改String值的方法,实际上都是创建一个全新的String对象,以包含修改后 ...
- 20175209 《Arrays和String单元测试》
20175209 <Arrays和String单元测试> 题目 在IDEA中以TDD的方式对String类和Arrays类进行学习,测试相关方法的正常,错误和边界情况 String类 ch ...
- codeforces-1136 (div2)
A.读到第i章,就有N - i + 1章还没读. #include <map> #include <set> #include <ctime> #include & ...
- 老男孩Python全栈学习 S9 日常作业 012
1.斐波那契数列用递归实现:问第n个斐波那契数是多少 def fbnq(n): if n == 0 or n == 1: return 1 else: return fbnq(n-1)+fbnq(n- ...