2.输出起始点为x轴最左边的点,
3.按照顺时针方向输出,
4.每个点必须是凸边形的顶点(不输出边上或凸边形内的点)。
输入样例: 3;1,2;2,2;3,3 输出样例: 1,2;3,3;2,2
注: - 输入数据的第一个数为点的数目,然后是分号;再后面就是以分号间隔的点; 点的数目最少为3个,最多为65535;该题目和斜率相关。
与其说这道题跟斜率有关,不如说是更二维向量,也就直线方向有关,用于判断依次连接直线时的下一个点的选择。所以要对不同方向直线进行量化。
思路记录:
1.一堆点,从最左边最下边的点开始连线。从第一个点开始,被连接的下一个点的判断方法决定了最终的多边形是否符合要求。
2.如何判断下一个被连接的点?每一次连接后得到的直线无非在四个象限(以原点为起始点),如下图。对曲线方向进行量化。选择下一个点的条件是:每一次连接后必须使得新的直线的方向量化值比前一条直线更大;在满足前一条基础上,方向量化值又要最小。
3.直线方向量化方式是,不管用什么方法,要使得依次处于1,2,3,4象限的直线的量化值越来愈大,反映出位置关系就行。
//2016华为机试题目:最大的凸多边形 #include<iostream> #include<sstream> #include<string> #include<vector> #include<cmath> using namespace std; struct Point { double x; double y; //bool flag; }; double quant_loc(Point p1,Point p2) { double dx=p2.x-p1.x; double dy=p2.y-p1.y; double l=sqrt(dx*dx+dy*dy); double quant; if(l!=0) { if(dx>=0&&dy>=0) quant=dx/l; else if(dx>=0&&dy<0) quant=-dy/l+1; else if(dx<0&&dy<0) quant=-dx/l+2; else if(dx<0&&dy>=0) quant=dy/l+3; } else quant=-100;//表示同一个点 return quant; } int find_next(int curr, double &last_quant,vector<Point> vec_p)//寻找该点的下一个连接点 { double curr_quant=5; int N=vec_p.size(); int next; double quanti; vector<int> vec_quant(N,-1); for(int i=0;i<N;i++) { quanti=quant_loc(vec_p[curr],vec_p[i]); if(quanti>last_quant&&quanti<curr_quant) { curr_quant=quanti; next=i; } else if(quanti==last_quant)//方向系数相等时 { curr_quant=quanti; next=i; } } last_quant=curr_quant; return next; } void main() { Point p1; Point p2; double val; string Str; //cin>>p1.x>>p1.y>>p2.x>>p2.y; //val=quant_loc(p1,p2); //cout<<val<<endl; while(getline(cin,Str)) { stringstream ss; ss.clear(); ss.str(""); ss<<Str; int N; ss>>N;//第一个数,点数 ss>>Str;//输出剩余字符 vector<Point> vec_p(N); double fistpx=100000000;// double fistpy=100000000;// int loc_first=0; for(int i=0;i<N;i++)//取出所有的数据点并找到第一个点 { ss.clear(); Str.erase(Str.begin()); ss<<Str; ss>>vec_p[i].x;//取x ss>>Str; double tempx=vec_p[i].x; ss.clear(); Str.erase(Str.begin()); ss<<Str; ss>>vec_p[i].y;//取y ss>>Str; double tempy=vec_p[i].y; if(tempx<fistpx) { fistpx=tempx;//用于比较 fistpy=tempy; loc_first=i;//记录第一个点 } else if(tempx==fistpx&&tempy<fistpy) { fistpx=tempx; fistpy=tempy; loc_first=i; } } //for(int i=0;i<N;i++) //cout<<vec_p[i].x<<" "<<vec_p[i].y<<' '<<loc_first<<endl; int curr=loc_first; vector<int> linep; double last_quant=-1; linep.push_back(curr); int next=find_next(curr, last_quant,vec_p);//寻找该点的下一个连接点 curr=next; linep.push_back(curr); while((vec_p[next].x!=vec_p[loc_first].x)||(vec_p[next].y!=vec_p[loc_first].y)) { next=find_next(curr, last_quant, vec_p); curr=next; linep.push_back(curr); } for(int i=0;i<linep.size();i++) { cout<<vec_p[linep[i]].x<<','<<vec_p[linep[i]].y<<';'; } cout<<endl; } } //还存在的问题:得到的结果在边上可能有点。