http://acm.hdu.edu.cn/showproblem.php?pid=5025
TLE了好几次
写的时候,问题在于,
1、钥匙怎么处理
参考了他人的写法,vis[key_num][i][j],相当于将图多维化,这样就可以判重了,否则只是按照普通的BFS,钥匙数不同的时候,可以重复,这个代码难易表达出来
另外此处一个很好的优化,当cost_now<cost[key_now][x_now][y_now]的时候,才q.push(Node) 这个剪枝很好啊
2、蛇怎么处理
没蛇的话,第一次搜到的可行解就是最优解,
有蛇的话,需要解决1、第一次遇到蛇杀死,以后遇到不杀,这个用set存储,每次find,注意只把曾经有蛇的地方insert,因为蛇只有5个,所以这个空间是开的下的,时间也承受的住 2、彻底将图搜完才可以结束搜索
//#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <iostream> #include <iomanip> #include <cmath> #include <map> #include <set> #include <queue> using namespace std; #define ls(rt) rt*2 #define rs(rt) rt*2+1 #define ll long long #define ull unsigned long long #define rep(i,s,e) for(int i=s;i<e;i++) #define repe(i,s,e) for(int i=s;i<=e;i++) #define CL(a,b) memset(a,b,sizeof(a)) #define IN(s) freopen(s,"r",stdin) #define OUT(s) freopen(s,"w",stdout) const ll ll_INF = ((ull)(-1))>>1; const double EPS = 1e-8; const double pi = acos(-1.0); const int INF = 100000000; const int MAXN = 100+10; int n,m,kx,ky,tx,ty; char mat[MAXN][MAXN]; int vis[10][MAXN][MAXN]; struct Node{ int x,y,k,cost; Node(){}; Node(int xx,int yy,int kk, int cc){x=xx;y=yy;k=kk;cost=cc;} set< pair<int, int> >s; }; int dir[4][2]={ {-1,0},{0,-1},{1,0},{0,1} }; queue<Node>q; bool legal(int x, int y) { if(x>=0 && y>=0 && x<n && y<n)return 1; else return 0; } int bfs() { int ret=INF; q.push( Node(kx,ky,0,0) ); CL(vis,0xff); while(!q.empty()) { Node tmp=q.front();q.pop(); for(int i=0;i<4;i++) { int x=tmp.x+dir[i][0]; int y=tmp.y+dir[i][1]; if(mat[x][y]=='#' || !legal(x,y))continue; Node nxt=tmp; nxt.x=x; nxt.y=y; nxt.cost++; if(mat[x][y] >= '1' && mat[x][y] <='9') { int num=mat[x][y]-'1'; if(num == tmp.k) { nxt.k=num+1; } } if(mat[x][y] == 'S' && tmp.s.find(make_pair(x,y)) == tmp.s.end()) { nxt.cost++; nxt.s.insert(make_pair(x,y)); } if(vis[nxt.k][x][y]>nxt.cost || vis[nxt.k][x][y]==-1) { vis[nxt.k][x][y]=nxt.cost; q.push(nxt); } } } return vis[m][tx][ty]; } int main() { //IN("hdu5025.txt"); while(~scanf("%d%d",&n,&m) && n+m) { getchar(); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { mat[i][j]=getchar(); if(mat[i][j] == 'K'){kx=i;ky=j;} if(mat[i][j] == 'T'){tx=i;ty=j;} } getchar(); } while(!q.empty())q.pop(); int ans=bfs(); if(ans == -1)printf("impossible\n"); else printf("%d\n",bfs()); } return 0; }
时间: 2024-10-18 16:47:43