P1135 奇怪的电梯
2018-02-01 14:34
204 查看
题目描述
呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第i层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有-2楼。那么,从A楼到B楼至少要按几次按钮呢?
输入输出格式
输入格式:
输入文件共有二行,第一行为三个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N),第二行为N个用空格隔开的非负整数,表示Ki。
输出格式:
输出文件仅一行,即最少按键次数,若无法到达,则输出-1。
输入输出样例
输入样例#1: 复制
5 1 5
3 3 1 2 5
输出样例#1: 复制
3
练习练习
这里附上三种解法:
怪怪的dp
Spfa+链式前向星
Dijkstra
呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第i层楼(1<=i<=N)上有一个数字Ki(0<=Ki<=N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如:3 3 1 2 5代表了Ki(K1=3,K2=3,……),从一楼开始。在一楼,按“上”可以到4楼,按“下”是不起作用的,因为没有-2楼。那么,从A楼到B楼至少要按几次按钮呢?
输入输出格式
输入格式:
输入文件共有二行,第一行为三个用空格隔开的正整数,表示N,A,B(1≤N≤200, 1≤A,B≤N),第二行为N个用空格隔开的非负整数,表示Ki。
输出格式:
输出文件仅一行,即最少按键次数,若无法到达,则输出-1。
输入输出样例
输入样例#1: 复制
5 1 5
3 3 1 2 5
输出样例#1: 复制
3
练习练习
这里附上三种解法:
怪怪的dp
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define inf 999999999 int n,s,e; int arr[1000]; int dp[1000]; int main() { cin>>n>>s>>e; for(int i=1; i<=n; i++)cin>>arr[i]; dp[s]=1; bool flag=true; //实现不断的更新 while(flag) { flag=false; for(int i=1; i<=n; i++) { if(dp[i]) { int down=i-arr[i]; int up=i+arr[i]; if(down>0) { if(dp[down]==0||dp[down]>dp[i]+1) { flag=true; dp[down]=dp[i]+1; } } if(up<=n) { if(dp[up]==0||dp[up]>dp[i]+1) { flag=true; dp[up]=dp[i]+1; } } } } } cout<<dp[e]-1; return 0; }
Spfa+链式前向星
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define inf 999999999 const int maxn=5000; int n,sx,ex; //链式前向星存图 int e[maxn],Head[maxn],Next[maxn]; int tot=0; //spfa int dis[maxn]; bool vis[maxn]; queue<int>que; //存图 void init(int x,int y) { tot++; e[tot]=y; Next[tot]=Head[x]; Head[x]=tot; } void spfa(int k) { dis[k]=0; que.push(k); vis[k]=true; while(!que.empty()) { int x=que.front(); vis[x]=false; que.pop(); for(int p=Head[x]; p; p=Next[p]) { int y=e[p]; if(dis[y]>dis[x]+1) { dis[y]=dis[x]+1; if(!vis[y]) { vis[y]=true; que.push(y); } } } } } int main() { fill(dis,dis+4000,inf); cin>>n>>sx>>ex; for(int i=1; i<=n; i++) { int x; cin>>x; if(i-x>0)init(i,i-x); if(i+x<=n)init(i,i+x); } spfa(sx); if(dis[ex]==inf)cout<<-1; else cout<<dis[ex]; return 0; }
Dijkstra
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define inf 999999999 const int maxn=5000; int n,a,b; int d[maxn][maxn]; int dis[maxn]; int vis[maxn]; int main() { cin>>n>>a>>b; for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) d[i][j]=inf; d[i][i]=0; } for(int i=1; i<=n; i++) { int x; cin>>x; if(i-x>0)d[i][i- 4000 x]=1; if(i+x<=n)d[i][i+x]=1; } for(int i=1; i<=n; i++) dis[i]=d[a][i]; for(int i=1; i<=n; i++) { int minn=inf; int t; for(int j=1; j<=n; j++) if(vis[j]==0&&dis[j]<minn) { minn=dis[j]; t=j; } vis[t]=1; for(int j=1; j<=n; j++) dis[j]=min(dis[j],dis[t]+d[t][j]); } if(dis[b]==inf)cout<<-1; else cout<<dis[b]; return 0; }
相关文章推荐
- 洛谷P1135 奇怪的电梯
- P1135 奇怪的电梯
- 洛谷 P1135 奇怪的电梯
- 洛谷 P1135 奇怪的电梯
- 洛谷P1135 奇怪的电梯
- 洛谷 P1135 奇怪的电梯 (dfs)
- P1135 奇怪的电梯
- 洛谷 P1135 奇怪的电梯
- 洛谷p1135 奇怪的电梯
- P1135 奇怪的电梯
- 洛谷P1135 奇怪的电梯
- luogu P1135 奇怪的电梯
- P1135 奇怪的电梯
- 洛谷 P1135 奇怪的电梯 (搜索)
- 洛谷 P1135 奇怪的电梯
- 洛谷OJ - P1135 - 奇怪的电梯(DFS+回溯+减枝)
- DP 洛谷 P1135 奇怪的电梯
- 奇怪的电梯 bfs
- 【Optimal Path】Lift.cpp 奇怪的电梯
- 奇怪的电梯