題意:有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;
}