 /**//*
題意:給出一個地圖,起點為Y,走到R花費為3,走到T為2,走到.為1,走到E旁邊就沒有了,不能停在P
問一開始給出錢C,能走到的所有地方
一開始我用BFS,我把錢也當做狀態,表示成(x,y,C),幾經優化才不TLE
主要優化在C,因為從起點都最遠的點花費為:(max(N-1-sx,sx)+max(M-1-sy,sy))*3
所以一開始時超過時就修改成這樣,然后手寫隊列就能在600ms左右AC

發現題意是求能夠走到的所有地方,所以錢多走到同一個地方當然比錢少走到同一個地方更好,因為前者
還能繼續走更多的路,上面的BFS就把錢多、錢少都考慮了!
現在就用visit[x,y]記錄到達x,y的最大值即可,用SPFA更新!
這樣一來,狀態只用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;
}

|
|
常用鏈接
隨筆分類
Links
搜索
最新評論

|
|