/**//* 题意:给出一个地图,起点为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
搜索
最新评论
|
|