题目
最小步数
这有一个迷宫,有0~8行和0~8列:
1,1,1,1,1,1,1,1,1
1,0,0,1,0,0,1,0,1
1,0,0,1,1,0,0,0,1
1,0,1,0,1,1,0,1,1
1,0,0,0,0,1,0,0,1
1,1,0,1,0,1,0,0,1
1,1,0,1,0,1,0,0,1
1,1,0,1,0,0,0,0,1
1,1,1,1,1,1,1,1,1
0表示道路,1表示墙。
现在输入一个道路的坐标作为起点,再如输入一个道路的坐标作为终点,问最少走几步才能从起点到达终点?
(注:一步是指从一坐标点走到其上下左右相邻坐标点,如:从(3,1)到(4,1)。)
输入
第一行输入一个整数n(0
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
int v[10][10],vis[10][10],fa[10][10],dis[10][10],last_dir[10][10],dir[100],dx[4]= {0,0,-1,1},dy[4] {-1,1,0,0};
void create()
{
v[1][1]=1;
v[1][2]=1;
v[1][4]=1;
v[1][5]=1;
v[1][7]=1;
v[2][1]=1;
v[2][2]=1;
v[2][5]=1;
v[2][6]=1;
v[2][7]=1;
v[3][1]=1;
v[3][3]=1;
v[3][6]=1;
v[4][1]=1;
v[4][2]=1;
v[4][3]=1;
v[4][4]=1;
v[4][6]=1;
v[4][7]=1;
v[5][2]=1;
v[5][4]=1;
v[5][6]=1;
v[5][7]=1;
v[6][2]=1;
v[6][4]=1;
v[6][6]=1;
v[6][7]=1;
v[7][2]=1;
v[7][4]=1;
v[7][5]=1;
v[7][6]=1;
v[7][7]=1;
}
void bfs(int x,int y)
{
int u,d,m=8;
queue<int>q;
if(!vis[x][y])
vis[x][y]=1;
u=x*8+y;
fa[x][y]=u;
dis[x][y]=0;
q.push(u);
while(!q.empty())
{
u=q.front();
q.pop();
x=u/m;
y=u%m;
// cout<<"x="<<x<<" y="<<y<<endl;
for(int d=0; d<4; d++)
{
int nx=x+dx[d];
int ny=y+dy[d];
if(nx>=0&&nx<=m&&ny>=0&&ny<=m&&v[nx][ny]&&!vis[nx][ny])
{
int v=nx*m+ny;
q.push(v);
vis[nx][ny]=1;
// fa[nx][ny]=u;
dis[nx][ny]=dis[x][y]+1;
// if(nx==c&&ny==d)cout<<"nx="<<nx<<" ny="<<ny;
// last_dir[nx][ny]=d;
}
}
}
}
int main()
{
memset(v,0,sizeof(v));
create();//创建的方法不适当,应该直接粘贴赋值
// for(int i=0; i<9; i++)//将输入的值输出,保证数据输入的正确
// {
// for(int j=0; j<9; j++)
// printf("%d ",v[i][j]);
// cout<<endl;
// }
// for(int i=0;i<4;i++)
// cout<<" dx "<<dx[i]<<" dy "<<dy[i];
int n,t,a,b,c,d;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
scanf("%d%d%d%d",&a,&b,&c,&d);
bfs(a,b);
cout<<dis[c][d]<<endl;
}
return 0;
}
同时这里用memset()将数组初始化为1时出现了错误,memset()函数初始化为0或者-1都不会出错,正数就报错了
另外又用广搜写了吝啬的国度,
#include<iostream>
#include<vector>
#include<cstdlib>
#include<queue>
#include<cstring>
using namespace std;
struct city //定义一个结构体
{
int vertex; //存储节点的下一个到达的head[vertex]节点
struct city *next; //从当前head[root]节点继续循环
};
typedef struct city *graph; //定义结构体指针
struct city head[100009]; //定义结构体数组
int vis[100009],ans[100009];//vis表示是否遍历过,ans数组用于存储每个节点的父亲节点
void create(int n)//将邻接表创建
{
graph ptr,newnode;
int from,to;
for(int i=0;i<n-1;i++)
{
cin>>from>>to;
newnode=( graph ) malloc(sizeof(struct city));//创建空间节点
newnode->vertex=to;
newnode->next=NULL;
ptr=&(head[from]);
while(ptr->next!=NULL)//循环到末尾
ptr=ptr->next;
ptr->next=newnode;
newnode=(graph)malloc(sizeof(struct city));
newnode->vertex=from;
newnode->next=NULL;
ptr=&(head[to]);
while(ptr->next!=NULL)
ptr=ptr->next;
ptr->next=newnode;
}
// for(int j=1;j<=n;j++)
// {
// ptr=&(head[j]);
// while(ptr!=NULL)
// {
// cout<<ptr->vertex<<" ==> ";
// ptr=ptr->next;
// }
// cout<<endl;
// }
}
void bfs(int root)//广搜
{
graph p;
queue<int> que;
que.push(root);
vis[root]=1;//将根入队列
while(!que.empty())
{
int v=que.front();//出队列
p=&(head[v]);
while(p!=NULL)//一定要循环到末尾
{
if(!vis[p->vertex])
{
ans[p->vertex]=v;
vis[p->vertex]=1;
que.push(p->vertex);
}
p=p->next;
}
que.pop();//记住每次要将用过的 队列pop,下一个才会是新的头
}
}
int main()
{
int m,n,s;
cin>>m;
while(m--)
{
memset(vis,0,sizeof(vis));//初始化
memset(ans,0,sizeof(ans));
for(int i=1;i<100009;i++)
{
head[i].vertex=i;//初始化
head[i].next=NULL;
}
cin>>n>>s;
create(n);
ans[s]=-1;
bfs(s);
for(int k=1;k<=n;k++)
cout<<ans[k]<<" ";
cout<<endl;
}
return 0;
}