题意:有n*m(1 <= n m <= 50)的格子,-1代表不能走的地方,0代表空地,整数k(1<=k<=5)代表当前格子被k号怪物控制,但是每个怪物不一定在自己
控制的范围内,一个人从给定的源点走到终点,每回合能走l移动值(1<=l<=10)块空地(如果k号怪物被打死了那么k号怪物控制的范围视为空地),
如果走到一个编号问k且k号怪物还没死的空地,那么移动值立刻减为0,问最少要几个回合能走到终点。
题解:比赛的时候已经想到了四维记录状态[i][j][k][l]表示到达i j 位置打死怪物的状态为 k 剩余步数为 l 的最小回合数,但是更新时候的一个状态被我搞没了,
一直在wa,比赛之后也wa了好久,还是自己的模拟功力不够吧唉,伤心……
Sure原创,转载请注明出处。
#include <iostream> #include <cstdio> #include <memory.h> #include <queue> using namespace std; const int inf = 1 << 29; const int maxn = 52; const int maxk = 7; const int maxl = 12; const int move[4][2] = {{-1,0},{0,1},{1,0},{0,-1}}; struct ddd { int x,y; int st,le; int turn; bool operator < (const ddd &other) const { if(turn == other.turn) { return le < other.le; } return turn > other.turn; } }; int mon[maxn][maxn],map[maxn][maxn]; bool vis[maxn][maxn][1 << maxk][maxl]; priority_queue <ddd> Q; int k,m,n,l,sx,sy,ex,ey; void read() { memset(vis,false,sizeof(vis)); memset(mon,0,sizeof(mon)); for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { scanf("%d",&map[i][j]); } } scanf("%d",&k); int x,y; for(int i=1;i<=k;i++) { scanf("%d %d",&x,&y); mon[x][y] = i; } scanf("%d %d %d %d",&sx,&sy,&ex,&ey); return; } bool judge(int x,int y) { if(x >= 1 && y >= 1 && x <= m && y <= n && map[x][y] != -1) { return true; } return false; } void bfs() { if(sx == ex && sy == ey) //源点和终点重合 { puts("0"); return; } int res = -1; while(!Q.empty()) Q.pop(); ddd cur,tmp; tmp.x = sx; tmp.y = sy; tmp.st = 0; tmp.le = 0; tmp.turn = 0; vis[sx][sy][0][0] = true; Q.push(tmp); //加入起始状态 while(!Q.empty()) { cur = Q.top(); Q.pop(); if(cur.x == ex && cur.y == ey) { res = cur.turn; break; } if(cur.le == 0) //开始时我把到达每个点剩余步数为0的状态扔掉了…… { cur.turn++; cur.le = l; if(vis[cur.x][cur.y][cur.st][cur.le] == false) { vis[cur.x][cur.y][cur.st][cur.le] = true; Q.push(cur); } continue; } for(int i=0;i<4;i++) { int xx = cur.x + move[i][0]; int yy = cur.y + move[i][1]; if(judge(xx , yy)) { int ss,tt,ll; if(map[xx][yy] == 0 || cur.st & (1 << (map[xx][yy] - 1))) { ss = cur.st; if(mon[xx][yy]) { ss |= (1 << (mon[xx][yy] - 1)); } tt = cur.turn; ll = cur.le - 1; } else { if(mon[xx][yy] == 0) { ss = cur.st; tt = cur.turn; ll = 0; } else { ss = cur.st | (1 << (mon[xx][yy] - 1)); tt = cur.turn; ll = 0; } } if(vis[xx][yy][ss][ll] == false) { vis[xx][yy][ss][ll] = true; tmp.x = xx; tmp.y = yy; tmp.st = ss; tmp.turn = tt; tmp.le = ll; Q.push(tmp); } } } } if(res == -1) puts("We need God's help!"); else printf("%d\n",res); return; } int main() { while(~scanf("%d %d %d",&m,&n,&l)) { read(); bfs(); } return 0; }