【思维】构造+凸包+向量叉积——LEETCODE 游乐园的迷宫

构造方法:设当前点是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;
    }
};

 

posted on 2020-06-04 13:24  zsben  阅读(155)  评论(0编辑  收藏  举报

导航