寻找凸包
点集Q的凸包ch(Q)是一个最小的凸多边形P,它满足Q中的每个点或者在P的边界上,或者在P的内部。现对于给定的点集Q,求Q的凸包ch(Q)的顶点集合。
输入:
输入有若干组测试数据。每一组测试数据的第一行上有整数n,表示该组测试数据有n个点组成的。接下来有n行,其每一行上有二个正整数,之间用一个或几个空格隔开。当输入行上只有一个数0时,表示输入结束。
输出:
对第i组测试数据,先输出"set i:",然后在下一行上输出该凸包的顶点集合,要求先输出凸包的顶点中纵坐标最小且靠最左边的点,然后将凸包的其它顶点按顺时针方向列出。
输入样例:
6
1 1
2 2
1 3
2 3
3 1
3 3
0
输出样例:
set 1:
(1,1)(3,1)(3,3)(1,3)
//------code------
#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include<stack>
using namespace std;
ifstream fin("input.txt");
ofstream fout("out.txt");
int multi(int p1,int p2,int p3);
int Point[100][2];
template<typename T>
std::string toString(const T& t) {
std::ostringstream s;
s << t;
return s.str();
}
int main()
{
int n,i=0;
fin>>n;
while(i<n){
fin>>Point[i][0]>>Point[i][1];
i++;
}
int m=Point[0][1],t=0;
for(int k=1;k<n;k++){
if (Point[k][1]<m)
{
m=Point[k][1];t=k;
}
else if(Point[k][1]==m)
{
if (Point[k][0]<Point[t][0])
{m=Point[k][1];t=k;}
}
}
Point[i][0] = Point[t][0];
Point[i][1] = Point[t][1];
int q=i;
stack<int> p;
p.push(t);
int kk=t,g=0;
while(true)
{
for(int i=1;i<=n;i++)
g= multi(kk,g,i);
if(g==q)break;
p.push(g);
kk=g;
g=0;
}
fout<<"Set: 1"<<endl;
int get;
string r="";
while(!p.empty())
{
get = p.top();
r = "("+toString(Point[get][0])+","+toString(Point[get][1])+")"+r;
p.pop();
}
fout<<r;
}
int multi(int p1,int p2,int p3)
{
int v;
int v1x=Point[p2][0]-Point[p1][0],
v1y=Point[p2][1]-Point[p1][1],
v2x=Point[p3][0]-Point[p1][0],
v2y=Point[p3][1]-Point[p1][1];
if(p1==p2) return p3;
if(p1==p3) return p2;
else{
v=v1x*v2y-v1y*v2x;
if(v>0) return p2;
if(v<0) return p3;
if(v==0){
if((v1x*v1x+v1y*v1y)>(v2x*v2x+v2y*v2y))
return p2;
else
return p3;
}
}
}