圈水池 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:圈水池(凸包入门)
题目链接 将所有点按从左至右顺序排序,然后将所有点先从左到右扫描再从右到左扫描,逐渐将凸包轮廓"勾勒"出来 (凸包轮廓满足,轮廓上连续的三个点按先后顺序给出的话呈逆时针方向) 最后 ...
随机推荐
- MYSQL 双主配置
MYSQL1. 版本号:5.7.243. 部署方式:双主部署,两台机器即是主又是备 ,双向拷贝,可以同时写入.4. 安装部署路径: a) /home/softb) 配置路径 /etc/my.cnfc) ...
- Markdown语法基础
Markdown基本语法 创建 2018-09-07 by YANHAI 标题:Setext方式 三个或更多 大标题 === 小标题 --- 大标题 小标题 标题:Atx方式 # 内容 (一级标题) ...
- lazyMan
class Lazyman { constructor() { this.tasks = []; this.init(); } init() { const task = () => { con ...
- webpack code splitting
一.代码分割优化 const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-webpack-plugin' ...
- [转帖]万字详解Oracle架构、原理、进程,学会世间再无复杂架构
万字详解Oracle架构.原理.进程,学会世间再无复杂架构 http://www.itpub.net/2019/04/24/1694/ 里面的图特别好 数据和云 2019-04-24 09:11:59 ...
- ElasticSearch搜索(一)
首先从ES的支持的字段说起,ES文档中字段有多种类型 官方文档. 这几个比较常用: text,keyword,integer,float,boolean,object,geo_point(地理坐标), ...
- QProcess与外部程序的调用
项目做到一定阶段,常常须要在原来的project上调用外部程序. Qt为此提供了QProcess类,QProcess可用于完毕启动外部程序,并与之交互通信. 一.启动外部程序的两种方式:(1)一体式: ...
- P1462 通往奥格瑞玛的道路
P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...
- EOF输入
EOF是一个计算机术语,为End Of File的缩写,在操作系统中表示资料源无更多的资料可读取.资料源通常称为档案或串流.通常在文本的最后存在此字符表示资料结束.是int类型的宏定义,它扩展为负整数 ...
- LOJ#2668 书法家
题意:要在一张网格纸上画出NOI图形,使得所占格子的权值和最大. 解:暴力DP即可... 从左往右,每个字母都可以被划分成三块,且每块都可用上下两维来表示. 于是一块一块的DP.考虑如何O(1)转移. ...