http://acm.hdu.edu.cn/viewcode.php?rid=22225154
因为总共a-j有10种钥匙,所以可以把有没有钥匙的状态压到一个int数里,然后dfs。
昨天状态特别不好写超时了好几次,但是这个题很简单的,算是水题。
代码
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 const int maxn=200000; 9 const double eps=1e-8; 10 const int modn=998244353; 11 int vis[21][21][1<<11]={}; 12 char a[21][21]={}; 13 int id1[4]={0,0,1,-1};int id2[4]={1,-1,0,0}; 14 int m,n,t; 15 struct nod{ 16 int x,y,k,t; 17 }; 18 queue<nod>q; 19 int bfs(int xi,int yi){ 20 while(!q.empty()){ 21 q.pop(); 22 } 23 nod c; int i,j,ff,ff1; 24 c.x=xi,c.y=yi,c.k=0,c.t=0; 25 vis[xi][yi][0]=1; 26 q.push(c); 27 while(!q.empty()){ 28 c=q.front(); 29 q.pop(); 30 nod b; 31 if(c.t+1>=t){ 32 return -1; 33 } 34 for(int zz=0;zz<4;zz++){ 35 i=c.x+id1[zz]; j=c.y+id2[zz]; 36 if(i<0||i>=n||j<0||j>=m||a[i][j]=='*'){ 37 continue; 38 }b.k=c.k; 39 if(a[i][j]=='^'){ 40 return c.t+1; 41 } 42 if(a[i][j]>='A'&&a[i][j]<='Z'){ 43 ff1=a[i][j]-'A'; 44 ff=c.k&(1<<ff1); 45 if(!ff)continue; 46 else if(!vis[i][j][b.k]) { vis[i][j][b.k]=1; b.x=i;b.y=j;b.t=c.t+1; q.push(b);} 47 } 48 if(a[i][j]>='a'&&a[i][j]<='z'){ 49 ff=a[i][j]-'a'; 50 b.k=c.k|(1<<ff); 51 if(!vis[i][j][b.k]) { vis[i][j][b.k]=1; b.x=i; b.y=j; b.t=c.t+1; q.push(b);} 52 } 53 if(a[i][j]=='.'&&!vis[i][j][b.k]){ 54 vis[i][j][b.k]=1; 55 b.x=i;b.y=j;b.t=c.t+1; 56 q.push(b); 57 } 58 } 59 } 60 return -1; 61 } 62 int main(){ 63 while(~scanf("%d%d%d",&n,&m,&t)){ 64 int x,y;memset(vis,0,sizeof(vis)); 65 for(int i=0;i<n;i++){ 66 scanf("%s",&a[i]); 67 for(int j=0;j<m;j++){ 68 if(a[i][j]=='@'){ 69 x=i;y=j; 70 a[i][j]='.'; 71 } 72 } 73 } 74 printf("%d ",bfs(x,y)); 75 } 76 }