题意:有n层电梯,当前处于A层,要到B层去,然后给你n个数,代表处在i层时会向下或者上走a[i]层,即到达i+a[i]或i-a【i】,求最小按电梯的次数(上下移动次数);
思路:简单题,没有什么思路,用最短路的Dijkstra和spfa就是简单地模板,两个bfs也挺简单。
我用四中方法做的,
首先是队列模拟bfs
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int a[250];//记录每层电梯上下的层数
int n,s,e;//n层,s是起始层,e是终止层
int mark[250];
int step[250];//记录到i层要step【i】步
int loc[250];//没有队列,就用这个数组模拟队列,存放走过的
void bfs()
{
int length,tail;
length=1;//增加和表示“队列”的长度
tail=0;//在数组里取出下一个数
loc[0]=s;
while(length>tail)
{
int x=loc[tail++];
if(x==e)
{
printf("%d\n",step[x]);
return;
}
int up=x+a[x];
if(mark[up]==0&&up>=1&&up<=n)
{
loc[length++]=up;
mark[up]=1;
step[up]=step[x]+1;
}
int down=x-a[x];
if(mark[down]==0&&down>=1&&down<=n)
{
loc[length++]=down;
mark[down]=1;
step[down]=step[x]+1;
}
}
printf("-1\n");
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n<=0) break;
scanf("%d%d",&s,&e);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
step[i]=0;
mark[i]=0;
}
if(s==e)
{
printf("0\n");
continue;
}
bfs();
}
return 0;
}
bfs队列做法:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
int a[250];//记录每层电梯上下的层数
int mark[250];
int step[250];//记录到i层要step【i】步
int n,s,e;//n层,s是起始层,e是终止层
void bfs()
{
queue<int>q;
int x,down,up;
while(!q.empty()) q.pop();
q.push(s);
while(!q.empty())
{
x=q.front();
q.pop();
if(x==e)
{
printf("%d\n",step[x]);
return;
}
up=x+a[x];
if(up>=1&&up<=n&&mark[up]==0)
{
q.push(up);
mark[up]=1;
step[up]=step[x]+1;
}
down=x-a[x];
if(down>=1&&down<=n&&mark[down]==0)
{
q.push(down);
mark[down]=1;
step[down]=step[x]+1;
}
}
printf("-1\n");
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n<=0) break;
scanf("%d%d",&s,&e);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
step[i]=0;
mark[i]=0;
}
if(s==e)
{
printf("0\n");
continue;
}
bfs();
}
return 0;
}
迪杰斯特拉做法:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define inf 5000;
using namespace std;
int n,s,e;
int a[250];
int dis[250];
int map[250][250];
int mark[250];
void Dijkstra()
{
for(int i=1;i<=n;i++)
{
dis[i]=map[s][i];
mark[i]=0;
}
for(int i=1;i<=n;i++)
{
int x,m=inf;
for(int j=1;j<=n;j++)
{
if(dis[j]<m&&mark[j]==0)
{
m=dis[j];
x=j;
}
}
mark[x]=1;
for(int j=1;j<=n;j++)
{
if(dis[x]+map[x][j]<dis[j]&&mark[j]==0)
{
dis[j]=dis[x]+map[x][j];
}
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n<=0) break;
scanf("%d%d",&s,&e);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=inf;
}
}
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(i+a[i]>=1&&i+a[i]<=n)
{
map[i][i+a[i]]=1;
}
if(i-a[i]>=1&&i-a[i]<=n)
{
map[i][i-a[i]]=1;
}
}
if(s==e)
{
printf("0\n");
continue;
}
Dijkstra();
if(dis[e]==5000)
{
printf("-1\n");
}
else
{
printf("%d\n",dis[e]);
}
}
return 0;
}
spfa做法:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<queue>
#define inf 50000
using namespace std;
struct node
{
int next;
int to;
int weight;
}life[550];
int mark[250];
int dis[250];
int head[250];
int a[250];
int n,s,e;int cur;
void init()
{
cur=1;
memset(head,-1,sizeof(head));
memset(life,0,sizeof(life));
for(int i=1;i<=n;i++)
{
dis[i]=inf;
mark[i]=0;
}
}
void add(int u,int v)
{
life[cur].to=v;
life[cur].weight=1;
life[cur].next=head[u];
head[u]=cur;
cur++;
}
void spfa_bfs()
{
queue<int>q;
int first,i;
while(!q.empty()) q.pop();
q.push(s);
dis[s]=0;
mark[s]=1;
while(!q.empty())
{
first=q.front();
q.pop();
mark[first]=0;
for(i=head[first];i!=-1;i=life[i].next)
{
if(life[i].weight+dis[first]<dis[life[i].to])
{
dis[life[i].to]=life[i].weight+dis[first];
if(mark[life[i].to]==0)
{
q.push(life[i].to);
mark[life[i].to];
}
}
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n<=0) break;
init();
scanf("%d%d",&s,&e);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(i+a[i]<=n)
add(i,i+a[i]);
if(i-a[i]>=1)
add(i,i-a[i]);
}
if(s==e)
{
printf("0\n");
continue;
}
spfa_bfs();
if(dis[e]>=inf)
{
printf("-1\n");
}
else
{
printf("%d\n",dis[e]);
}
}
return 0;
}