Solution: compression + DFS
1 #include <cstdio> 2 #include <cstring> 3 #include <set> 4 #define LL long long 5 using namespace std; 6 char table[23][23]; 7 int rows,cols,totKey[5],hasKey[5],sx,sy; 8 set<LL>vis; 9 bool isVis(int x,int y){10 LL temp = 0;11 for(int i = 0; i < 5; i++)12 temp = (temp<<9)+hasKey[i];13 temp = (temp<<10)+(x<<5)+y;14 if(vis.count(temp)) return true;15 vis.insert(temp);16 return false;17 }18 bool dfs(int x,int y) {19 if(table[x][y] == ‘X‘) return false;20 if(table[x][y] == ‘G‘)21 return true;22 if(isVis(x,y)) return false;23 static int dir[4][2] = {0,-1,0,1,-1,0,1,0};24 if(table[x][y] >= ‘a‘ && table[x][y] <= ‘e‘) {25 hasKey[table[x][y]-‘a‘]++;26 table[x][y] = ‘.‘;27 } else if(table[x][y] >= ‘A‘ && table[x][y] <= ‘E‘) {28 if(hasKey[table[x][y]-‘A‘] < totKey[table[x][y]-‘A‘])29 return false;30 }31 char ch = table[x][y];32 table[x][y] = ‘.‘;33 for(int i = 0; i < 4; i++)34 if(dfs(x+dir[i][0],y+dir[i][1])) return true;35 if(table[x][y] != ‘.‘) table[x][y] = ch;36 return false;37 }38 int main() {39 int i,j;40 while(scanf("%d %d",&rows,&cols),rows||cols) {41 memset(totKey,0,sizeof(totKey));42 memset(hasKey,0,sizeof(hasKey));43 memset(table,‘X‘,sizeof(table));44 for(i = 1; i <= rows; i++) {45 scanf("%s",table[i]+1);46 table[i][strlen(table[i])]=‘X‘;47 for(j = 1; j <= cols; j++) {48 if(table[i][j] == ‘S‘) {49 table[sx = i][sy = j] = ‘.‘;50 } else if(table[i][j] >= ‘a‘ && table[i][j] <= ‘e‘) {51 totKey[table[i][j]-‘a‘]++;52 }53 }54 }55 vis.clear();56 for(i = 0; i < 5; i++)57 if(!totKey[i]) totKey[i] = 500;58 printf("%s\n",dfs(sx,sy)?"YES":"NO");59 }60 return 0;61 }View code