leetcode 864. Shortest Path to Get All Keys

说一下简单思路

因为钥匙数目很少,可以直接用二进制保存所得的钥匙状态,所以,用6把钥匙+现在所在地点+已走的路径的长度来表示不同的状态,用队列queue实现广搜算法即可

ps:我之前用新建一个类来保存6把钥匙+当前所在地点,表示已经走过的状态,发现在重载<运算符(即cmp函数)的时候会报一些异常奇怪的错误,最后用pair来保存状态才过的,借此提示各位读者,set<class_name>要慎用,当然明白stl底层的大佬就随便用啦,,,好了,继续恶补stl源码

int desll[4][2]={{0,1},{0,-1},{1,0},{-1,0}};

struct poi{
    set<int> se;
    int head , len;
    poi(){}
    poi(set<int> sefunc, int x , int le):se(sefunc),head(x),len(le){}
};

class Solution {
public:
    int shortestPathAllKeys(vector<string>& grid) {
        int n = grid.size() , m = grid[0].size();
        int ins=0;
        set<pair<int,int> > seAll;
        int x=0,y=0;
        for(int i=0; i<n; i++){
            for(int j=0;j<m;j++){
                if(grid[i][j] <= 'z' && grid[i][j] >= 'a')ins++;
                if(grid[i][j] == '@'){
                    x = i;
                    y = j;
                }
            }
        }
        seAll.clear();
        queue<poi> qu;
        int NewHead=x*m+y;
        set<int> setShort;
        qu.push(poi(setShort, NewHead,0));
        seAll.insert(make_pair(0,NewHead));
        while(qu.size()){
            set<int> seMid = qu.front().se;
            int headMid = qu.front().head;
            int lenMid = qu.front().len;
            int u = headMid / m , v = headMid % m;
            if((int)seMid.size()==ins)return lenMid;
            lenMid++;
            qu.pop();
            for(int i=0; i<4; i++){
                int newx = u + desll[i][0] , newy = v + desll[i][1];
                if(newx >=0 && newx < n && newy >= 0 && newy < m && grid[newx][newy]!='#'){
                    set<int> seMidm = seMid;
                    if(grid[newx][newy]<='Z'&&grid[newx][newy]>='A'){
                        if(seMid.count(grid[newx][newy]-'A')==0)continue;
                    }
                    if(grid[newx][newy] <= 'z' && grid[newx][newy] >= 'a')
                        seMidm.insert(grid[newx][newy]-'a');
                    int newHead = newx * m + newy;
                    int arr[6]={0,0,0,0,0,0};
                    int paFir=0;
                    for(auto au=seMidm.begin();au!=seMidm.end();au++)paFir ^= (1<<(*au));
                    if(seAll.count(make_pair(paFir , newHead))==0){
                        seAll.insert(make_pair(paFir , newHead));
                        qu.push(poi(seMidm , newHead , lenMid));
                    }
                }
            }
        }
        return -1;
    }
};

猜你喜欢

转载自blog.csdn.net/jfnfjivkdnfjf/article/details/81019593