structT{inti;intj;intkeys;// Keys in bitmaskT(inti,intj,intkeys):i(i),j(j),keys(keys){}};classSolution{public:intshortestPathAllKeys(vector<string>&grid){constintm=grid.size();constintn=grid[0].length();constintkeysCount=getKeysCount(grid);constintkKeys=(1<<keysCount)-1;constvector<int>dirs{0,1,0,-1,0};constvector<int>start=getStart(grid);intans=0;queue<T>q{{{start[0],start[1],0}}};vector<vector<vector<bool>>>seen(m,vector<vector<bool>>(n,vector<bool>(kKeys)));seen[start[0]][start[1]][0]=true;while(!q.empty()){++ans;for(intsz=q.size();sz>0;--sz){constauto[i,j,keys]=q.front();q.pop();for(intk=0;k<4;++k){constintx=i+dirs[k];constinty=j+dirs[k+1];if(x<0||x==m||y<0||y==n)continue;constcharc=grid[x][y];if(c=='#')continue;constintnewKeys='a'<=c&&c<='f'?keys|1<<c-'a':keys;if(newKeys==kKeys)returnans;if(seen[x][y][newKeys])continue;if('A'<=c&&c<='F'&&((newKeys>>c-'A')&1)==0)continue;q.emplace(x,y,newKeys);seen[x][y][newKeys]=true;}}}return-1;}private:intgetKeysCount(constvector<string>&grid){intcount=0;for(conststring&s:grid)count+=std::count_if(begin(s),end(s),[](charc){return'a'<=c&&c<='f';});returncount;}vector<int>getStart(constvector<string>&grid){for(inti=0;i<grid.size();++i)for(intj=0;j<grid[0].length();++j)if(grid[i][j]=='@')return{i,j};throw;}};
classT{publicinti;publicintj;publicintkeys;// Keys in bitmaskpublicT(inti,intj,intkeys){this.i=i;this.j=j;this.keys=keys;}}classSolution{publicintshortestPathAllKeys(String[]grid){finalintm=grid.length;finalintn=grid[0].length();finalintkeysCount=getKeysCount(grid);finalintkKeys=(1<<keysCount)-1;finalint[]dirs={0,1,0,-1,0};finalint[]start=getStart(grid);intans=0;Queue<T>q=newArrayDeque<>(Arrays.asList(newT(start[0],start[1],0)));boolean[][][]seen=newboolean[m][n][kKeys];seen[start[0]][start[1]][0]=true;while(!q.isEmpty()){++ans;for(intsz=q.size();sz>0;--sz){finalinti=q.peek().i;finalintj=q.peek().j;finalintkeys=q.poll().keys;for(intk=0;k<4;++k){finalintx=i+dirs[k];finalinty=j+dirs[k+1];if(x<0||x==m||y<0||y==n)continue;finalcharc=grid[x].charAt(y);if(c=='#')continue;finalintnewKeys='a'<=c&&c<='f'?keys|1<<c-'a':keys;if(newKeys==kKeys)returnans;if(seen[x][y][newKeys])continue;if('A'<=c&&c<='F'&&(newKeys>>c-'A'&1)==0)continue;q.offer(newT(x,y,newKeys));seen[x][y][newKeys]=true;}}}return-1;}privateintgetKeysCount(String[]grid){intcount=0;for(finalStrings:grid)count+=(int)s.chars().filter(c->'a'<=c&&c<='f').count();returncount;}privateint[]getStart(String[]grid){for(inti=0;i<grid.length;++i)for(intj=0;j<grid[0].length();++j)if(grid[i].charAt(j)=='@')returnnewint[]{i,j};thrownewIllegalArgumentException();}}