一個很不錯的搜尋,剛看到題的時候一直沒明白題意。兩天后,也就是昨天下午終於理解了題意,英語不好 好慚愧
題意:
給出一個圖,門都在邊界上。只能從一個門進去。選擇耗費的最小時間。
‘*’是不能走通的牆
'.'是走廊,不耗費任意時間
'1'-'9'是需耗時1-9才能翻過的牆,如果使用一個炸彈炸毀,則不耗費任意時間
'#'、'A'-'Z'是門,可以帶1-26個炸彈。#是0個炸彈的門。
分析:
由題意,需要炸彈數作為狀態的一個屬性【炸彈數目不同是不同的走法】。
則圖可以分為兩個搜法:
1》到達”.“的時候不需要耗費時間、炸彈。
2》到達“1”,有兩個走法,直接走過去耗時1T,使用炸彈,耗時0T,耗費炸彈1顆。
這個代碼調試了很長時間【恍惚有一下午那麼久】,最後的最後才發現row值沒有每組資料都初始化、、、、、
代碼:
#include <stdio.h>#include<string.h>#include<queue>#include<iostream>using namespace std;char map[101][101];int state[101][101][27];//狀態數組int dis[4][2]={1,0,-1,0,0,1,0,-1};int row,col;int ss;struct info{int x;int y;int k;//子彈數int time;};queue<info>Q;bool operator<(info a,info b){return a.time>b.time;}void BFS(){info e;int i,j;memset(state,-1,sizeof(state));//各個入口入隊for(i=0;i<row;i++){for(j=0;j<col;j++){if(map[i][j]=='#'||(map[i][j]>='A'&&map[i][j]<='Z')) {e.x=i;e.y=j;e.time=0;if(map[i][j]=='#') e.k=0;else e.k=map[i][j]-'A'+1;Q.push(e);state[i][j][e.k]=0;map[i][j]='*';}}}//搜尋while(!Q.empty()){e=Q.front();Q.pop(); info f;for(int i=0;i<4;i++){f.x=e.x+dis[i][0];f.y=e.y+dis[i][1];if(map[f.x][f.y]=='*'||f.x<0||f.y>=col||f.y<0||f.x>=row) continue;if(map[f.x][f.y]=='.')//直接走過 {f.k=e.k;//炸彈還是原來的數if(state[f.x][f.y][f.k]==-1||state[f.x][f.y][f.k]>e.time){f.time=e.time;state[f.x][f.y][f.k]=f.time;Q.push(f);}}else if(map[f.x][f.y]>'0'&&map[f.x][f.y]<='9'){///////////沒有被搜尋過 或者 搜過但當前的方法是最省時間的if(e.k>0&&(state[f.x][f.y][e.k-1]==-1||state[f.x][f.y][e.k-1]>e.time))//炸{f.k=e.k-1;f.time=e.time;state[f.x][f.y][f.k]=f.time;Q.push(f);}if(state[f.x][f.y][e.k]==-1||state[f.x][f.y][e.k]>e.time+map[f.x][f.y]-'0')//不炸{f.k=e.k;f.time=e.time+map[f.x][f.y]-'0';state[f.x][f.y][f.k]=f.time;Q.push(f);}}else if(map[f.x][f.y]=='$'&&e.time<ss) ss=e.time;}}}int main(){while(1){row=0;while(gets(map[row])){if(map[row][0]=='-') return 0;if(strlen(map[row])<1) break;row++;}col=strlen(map[0]);ss=10000000;BFS();if(ss==10000000) printf("IMPOSSIBLE\n");else printf("%d\n",ss);}return 0;}