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; } } //還存在的問題:得到的結果在邊上可能有點。