算是做过的第一道正式记录路径的题目,还是纪念一下吧,虽然说,,,没有完全正确,,,
先贴上我的代码(不正确!!!)
//入口和出口也可能有怪兽,记录路径啊~~记录路径~~
//bfs+优先队列
#include
#include
#include
using namespace std;
struct node{
int x,y;
int times;
};
bool operator<(const node &a,const node &b)
{
return a.times>b.times;
}
int n,m,step;
char map[105][105];
int vis[105][105];
int fx[105],fy[105],k;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int judge(node p)
{
if(p.x<0 || p.x==n || p.y<0 || p.y==m)
return false;
if(map[p.x][p.y]=='X' || vis[p.x][p.y])
return false;
return true;
}
void bfs()
{
priority_queueQ;
node q,p;
q.x=q.y=0;
q.times=0;
if(map[q.x][q.y]!='.' && map[q.x][q.y]!='X')
q.times+=map[q.x][q.y]-'0';
vis[q.x][q.y]=1;
Q.push(q);
while(!Q.empty())
{
q=Q.top();
Q.pop();
fx[k]=q.x,fy[k++]=q.y;
//printf("%d %d %d\n",q.x,q.y,q.times);
if(q.x==n-1 && q.y==m-1)
{
step=q.times;
return ;
}
for(int i=0;i<4;i++)
{
p=q;
p.x+=dx[i];
p.y+=dy[i];
p.times++;
if(!judge(p))
continue;
if(map[p.x][p.y]!='.' && map[p.x][p.y]!='X')
p.times+=map[p.x][p.y]-'0';
vis[p.x][p.y]=1;
Q.push(p);
}
}
}
void printpath()
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",step);
int t=1;
for(int i=0;i(%d,%d)\n",t++,fx[i],fy[i],fx[i+1],fy[i+1]);
if(map[fx[i+1]][fy[i+1]]!='.' && map[fx[i+1]][fy[i+1]]!='X')
{
int tt=map[fx[i+1]][fy[i+1]]-'0';
while(tt>0)
{
printf("%ds:FIGHT AT (%d,%d)\n",t++,fx[i+1],fy[i+1]);
tt--;
}
}
}
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
memset(fx,0,sizeof(fx));
memset(fy,0,sizeof(fy));
for(int i=0;i
参考了大神的代码(大神说是简单的bfs,,,_QAQ_)之后,我很认真的分析了路径的保存问题
注意:
1、因为打怪兽要消耗时间,所以要用优先队列记录状态
2、需要输出路径,所以用flag[ i ] [ j ]记录朝向
关于路径问题,我通过画图发现,每个可以走的点都会被遍历到并且只能被遍历一次,但是从
起点到终点只有一条完整的路径。看下图,画叉的是障碍,三角中的数字是怪物的血量,其他每个
圆里的数字是走到该点所用的时间。我们发现,按照箭头的方向,我们只能找到一条从起点通往终
点的路,那么我们可以用一个二维数组flag记录下箭头的指向,最后从终点递归到起点,返回时输
出,就可以得到路径
5 6
.XX.1.
..X.2.
2...X.
...XX.
XXXXX.
附上AC代码:
#include
#include
#include
using namespace std;
struct node
{
int x,y;
int step;
};
bool operator<(node a,node b)
{
return a.step>b.step;
}
int map[105][105]; //地图
int flag[105][105];//flag[i][j]记录是怎么从上一个位置走到(i,j)的, 1代表(向下),2代表(向上),3代表(向左),4代表(向右)
int cnt[105][105];//记录怪的血量
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
int n,m,tim;
int check(int x,int y) //判断(x,y)是否可走
{
if(x<0 || y<0 || x>=n || y>=m)
return 1;
if(map[x][y] == -1)
return 1;
return 0;
}
int bfs()
{
int i;
priority_queue Q;
node a,next;
a.x = 0;
a.y = 0;
a.step = 0;
map[0][0] = -1;
Q.push(a);
while(!Q.empty())
{
a = Q.top();
Q.pop();
if(a.x == n-1 && a.y == m-1)
return a.step;
for(i = 0; i<4; i++)
{
next=a;
next.x+=dx[i];
next.y+=dy[i];
if(check(next.x,next.y))
continue;
next.step =a.step+map[next.x][next.y]+1;//记录时间
map[next.x][next.y]=-1;//标记为走过
flag[next.x][next.y]=i+1;//记录朝向
Q.push(next);
}
}
return 0;
}
void print(int x,int y) //递归输出路径
{
int n_x,n_y;
if(!flag[x][y])//回到起点,返回
return;
n_x = x - dx[flag[x][y]-1];
n_y = y - dy[flag[x][y]-1];
print(n_x,n_y);
printf("%ds:(%d,%d)->(%d,%d)\n",tim++,n_x,n_y,x,y);
while(cnt[x][y]--)
{
printf("%ds:FIGHT AT (%d,%d)\n",tim++,x,y);
}
}
int main()
{
int i,j;
while(~scanf("%d%d",&n,&m))
{
memset(map,0,sizeof(map));
memset(flag,0,sizeof(flag));
memset(cnt,0,sizeof(cnt));
char s[105];
for(i = 0; i