构造方法:设当前点是now,如果下一次向右转,那么下一个点就是未访问过的和now叉积最逆时针的那个;反之下一次左转,那么下一个点就是未访问过的和now叉积最顺时针的(意会一下即可)那个点
总之就是不断找最极端的点nxt,使其他所有点都在now->nxt的左侧和右侧,这样必定会有解,复杂度O(n^2)
class Solution { public: #define N 2005 inline vector<int> vec(vector<int>&k1,vector<int>k2){//k1->k2 k2[0]-=k1[0];k2[1]-=k1[1]; return k2; } inline int cross(vector<int>&k1,vector<int>&k2){ return k1[0]*k2[1]-k1[1]*k2[0]; } int n,vis[N]; vector<int> now,nxt; vector<int> visitOrder(vector<vector<int>>& points, string direction) { n=points.size(); nxt.resize(2);now.resize(2); vector<int>ans; int id=0; now=points[0]; for(int i=1;i<n;i++) if(points[i][0]<now[0])now=points[i],id=i; vis[id]=1; ans.push_back(id); for(int i=0;i<n-2;i++){ if(direction[i]=='L'){//下一步左转 int id; for(int j=0;j<n;j++)if(!vis[j])nxt=points[j],id=j; for(int j=0;j<n;j++)if(!vis[j]){ vector<int>p=vec(now,nxt); vector<int>q=vec(now,points[j]); if(cross(p,q)<0){ id=j;nxt=points[j]; } } vis[id]=1; ans.push_back(id); vis[id]=1; now=points[id]; }else {//下一步右转 int id; for(int j=0;j<n;j++)if(!vis[j])nxt=points[j],id=j; for(int j=0;j<n;j++)if(!vis[j]){ vector<int>p=vec(now,nxt); vector<int>q=vec(now,points[j]); if(cross(p,q)>0){id=j;nxt=points[j];} } vis[id]=1; ans.push_back(id); vis[id]=1; now=points[id]; } } for(int i=0;i<n;i++)if(!vis[i])ans.push_back(i); return ans; } };