 /**//*
題意:給出一個(gè)地圖,起點(diǎn)為Y,走到R花費(fèi)為3,走到T為2,走到.為1,走到E旁邊就沒(méi)有了,不能停在P
問(wèn)一開(kāi)始給出錢(qián)C,能走到的所有地方
一開(kāi)始我用BFS,我把錢(qián)也當(dāng)做狀態(tài),表示成(x,y,C),幾經(jīng)優(yōu)化才不TLE
主要優(yōu)化在C,因?yàn)閺钠瘘c(diǎn)都最遠(yuǎn)的點(diǎn)花費(fèi)為:(max(N-1-sx,sx)+max(M-1-sy,sy))*3
所以一開(kāi)始時(shí)超過(guò)時(shí)就修改成這樣,然后手寫(xiě)隊(duì)列就能在600ms左右AC

發(fā)現(xiàn)題意是求能夠走到的所有地方,所以錢(qián)多走到同一個(gè)地方當(dāng)然比錢(qián)少走到同一個(gè)地方更好,因?yàn)榍罢?br> 還能繼續(xù)走更多的路,上面的BFS就把錢(qián)多、錢(qián)少都考慮了!
現(xiàn)在就用visit[x,y]記錄到達(dá)x,y的最大值即可,用SPFA更新!
這樣一來(lái),狀態(tài)只用2維表示了!也很快15ms
*/
#include<cstdio>
#include<cstring>

const int MAXN = 10000;

 int dir[4][2]= { {0,1}, {1,0}, {0,-1}, {-1,0}};
char map[101][101];
bool in[101][101];
int visit[101][101];
int N,M,C,sx,sy;
int Q[MAXN][2];

bool bound(int x,int y)
  {
return x>=0&&x<N&&y>=0&&y<M;
}
void BFS()
  {
memset(in,0,sizeof(in));
memset(visit,-1,sizeof(visit));
int front=0,tail=1;
visit[sx][sy]=C;
for(Q[0][0]=sx,Q[0][1]=sy;front!=tail;front=(front+1)%MAXN)
 {
int x = Q[front][0],y=Q[front][1],c=visit[x][y];
in[x][y]=0;
for(int k=0;k<4;k++)
 {
int nx = x+dir[k][0],ny=y+dir[k][1];
if(!bound(nx,ny)||map[nx][ny]=='E'||map[nx][ny]=='#')continue;
char ch = map[nx][ny];
int nc = c-1;
if(ch=='T')nc-=1;
if(ch=='R')nc-=2;
if(nc<=visit[nx][ny])continue;
visit[nx][ny]=nc;
bool chk = false;
for(int kk=0;kk<4;kk++)
 {
int xx = nx+dir[kk][0],yy=ny+dir[kk][1];
 if(bound(xx,yy)&&map[xx][yy]=='E') {chk=true;break;}
}
if(chk||in[nx][ny])continue;
in[nx][ny]=1;
Q[tail][0]=nx,Q[tail][1]=ny;
tail=(tail+1)%MAXN;
}
}
}
int main()
  {
int T;
scanf("%d",&T);
while(T--)
 {
scanf("%d%d%d",&N,&M,&C);
 for(int i=0;i<N;i++) {
getchar();
 for(int j=0;j<M;j++) {
map[i][j]=getchar();
if(map[i][j]=='Y')sx=i,sy=j;
}
}
BFS();
 for(int i=0;i<N;i++) {
for(int j=0;j<M;j++)
if(map[i][j]=='P'||map[i][j]=='Y')putchar(map[i][j]);
else putchar(visit[i][j]>=0?'*':map[i][j]);
puts("");
}
puts("");
}
return 0;
}

|