analysis
Today, the most difficult, a well-matched opponents
First, do not be confused by the total points, total points 400, but the input required to tell us, to go and start and end points, including color, add up to no more than 20
Then we can consider like pressure to each point numbers, which indicate the state of a colored dot
This is just a state on the map it! Because the cube will take away the color, so set up another six states, represents a cube current whether each side has a color, remember to use the recommendations in this notebook at the time of writing, forget the dead, then turn transfer
Two conditions are brought together, the entire state 26, the cube of 6-bit state, the front 20 of the state of FIG.
Then we take into account that there will be repetition of the state, but just not enough to repeat this state, and sometimes on the map as cube, cube location but not the same!
Duplicate Status Available Ha Xijia adjacency table (or pointer) solution
The most disgusting part is that when you move the cube, your state of all six color variations to a wave, a lump-bit computing stack together
Also note that when a judgment, when the color state and a state below the current position is not the same state of the cube in FIG. (A color is not a color), they need to change state
Do not drive space burst, I just stuck in the past 12Wkb
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> #include <memory.h> #include <queue> #include <cstdlib> using namespace std; const int N=4e2+10; const int P=388211; struct SS { int u,S; }; struct QS { SS s; int dep; }; struct Graph { int v,nx; }e[10000000]; int cnt; int n,m; char c[N][N]; int id[N][N],icnt,g[21][4]; int sx,sy,tx,ty,sS; queue<QS> q; int p[21][517619]; bool Query(SS a) { int i=a.S%P; for (int j=p[a.u][i];j;j=e[j].nx) if (e[j].v==a.S) return 1; return 0; } void Insert(SS a) { int i=a.S%P; e[++cnt]=(Graph){a.S,p[a.u][i]};p[a.u][i]=cnt; } int Roll(int S,int type) { switch (type) { case 0:return (S&48)|((S&3)<<2)|((S&4)>>1)|((S&8)>>3); case 1:return (S&48)|((S&1)<<3)|((S&2)<<1)|((S&12)>>2); case 2:return ((S&3)<<4)|(S&12)|((S&16)>>3)|((S&32)>>5); case 3:return ((S&1)<<5)|((S&2)<<3)|(S&12)|((S&48)>>4); } } void Solve(int u,int bS,int cS,int dep) { if ((cS&1)^((bS>>u-1)&1)) cS^=1,bS^=(1<<u-1); if (!bS&&u==id[tx][ty]) { printf("%d",dep-1); exit(0); } int S=bS|(cS<<icnt); if (Query((SS){u,S})) return; q.push((QS){(SS){u,S},dep}); Insert((SS){u,S}); } void BFS() { q.push((QS){(SS){id[sx][sy],sS},1}); Insert((SS){id[sx][sy],sS}); while (!q.empty()) { QS a=q.front();q.pop(); int u=a.s.u,bS=a.s.S&((1<<icnt)-1),cS=a.s.S>>icnt,dep=a.dep; for (int i=0;i<4;i++) if (g[u][i]) { int scS=Roll(cS,i); Solve(g[u][i],bS,scS,dep+1); } } } int main() { scanf("%d%d",&m,&n); for (int i=1;i<=m;i++) scanf("%s",c[i]+1); for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) { if (c[i][j]!='#') id[i][j]=++icnt; if (c[i][j]=='C') sx=i,sy=j; if (c[i][j]=='G') tx=i,ty=j; if (c[i][j]=='P') sS|=(1<<icnt-1); } for (int i=1;i<=m;i++) for (int j=1;j<=n;j++) if (c[i][j]!='#') { if (i>1&&c[i-1][j]!='#') g[id[i][j]][0]=id[i-1][j]; if (i<m&&c[i+1][j]!='#') g[id[i][j]][1]=id[i+1][j]; if (j>1&&c[i][j-1]!='#') g[id[i][j]][2]=id[i][j-1]; if (j<n&&c[i][j+1]!='#') g[id[i][j]][3]=id[i][j+1]; } BFS(); }