广搜,值得学习的地方时是用二进制数来存储已获得的钻石种类。
#include <iostream> #include <memory.h> #include <vector> #include <queue> #include <stdio.h> #include <algorithm> #include <unordered_set> #include <set> #define IN (1<<28) using namespace std; struct node { int x,y,step, dia; node( int xx = 0, int yy = 0, int ss = 0, int dd = 0 ):x(xx), y(yy), step(ss), dia(dd) {} friend bool operator <(const node &a, const node &b ) { return a.step > b.step; } }; struct door { int x,y; door( int xx = 0, int yy = 0):x(xx), y(yy) {} }; door doors[15]; queue<node> q; int visited[205][205][1<<5], R, C, K, T, BeginX, BeginY, EndX, EndY, cnt; int dx[] = {1,-1,0,0}; int dy[] = {0,0,1,-1}; char Map[205][205]; void bfs() { if( K > 5 ) { printf("oop!\n"); return; } q.push( node( BeginX, BeginY, 0, 0 ) ); visited[BeginX][BeginY][0] = 1; while( !q.empty() ) { node now = q.front(); q.pop(); if( now.x == EndX && now.y == EndY && now.dia >= (1<<K) - 1 ) { printf("%d\n", now.step ); return; } if( Map[now.x][now.y] == '$' ) { for( int i = 0; i < cnt; i++ ) { if( !visited[ doors[i].x ][ doors[i].y ][ now.dia ] ) { q.push( node( doors[i].x, doors[i].y, now.step, now.dia ) ); visited[ doors[i].x ][ doors[i].y ][ now.dia ] = 1; } } } for( int i = 0; i < 4; i++ ) { int nowx = now.x + dx[i]; int nowy = now.y + dy[i]; if( Map[nowx][nowy] != '#' ) { if( Map[nowx][nowy] >= '0' && Map[nowx][nowy] <= '4' ) { int s; s = now.dia | (1<<Map[nowx][nowy]-'0'); if( !visited[nowx][nowy][s] ) { q.push( node( nowx, nowy, now.step + 1, s ) ); visited[nowx][nowy][s] = 1; } } else { if( !visited[nowx][nowy][now.dia] ) { q.push( node( nowx, nowy, now.step + 1, now.dia ) ); visited[nowx][nowy][now.dia] = 1; } } } } } printf("oop!\n"); return; } int main() { scanf("%d", &T); while( T-- ) { scanf("%d %d %d", &R, &C, &K); memset(visited, 0, sizeof(visited)); for( int i = 0; i < 205; i++ ) for( int j = 0; j < 205; j++ ) Map[i][j] = '0'; cnt = 0;//传送门数量 while( !q.empty() ) { q.pop(); } for( int i = 1; i <= R; i++ ) for( int j = 1; j <= C; j++ ) { cin >> Map[i][j]; if( Map[i][j] == 'S' ) { BeginX = i; BeginY = j; } else if( Map[i][j] == 'E' ) { EndX = i; EndY = j; } else if( Map[i][j] == '$' ) { doors[cnt].x = i; doors[cnt].y = j; cnt++; } } for( int i = 0; i <= R+1; i++ ) for( int j = 0; j <= C+1; j++ ) { if( i==0 || j==0 || i==R+1 || j==C+1 ) Map[i][j] = '#'; } bfs(); } return 0; }