华师一附中OI组
标题:
P1135 奇怪的电梯
[打印本页]
作者:
admin
时间:
2018-5-12 22:22
标题:
P1135 奇怪的电梯
https://www.luogu.org/problemnew/show/P1135
题目描述
呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第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
作者:
admin
时间:
2018-5-12 22:23
裸的BFS 当然也可以dijistra 其实所有的边长为1的时候 Dijistra不就是BFS吗?
作者:
黄煦喆
时间:
2018-6-2 20:51
本帖最后由 黄煦喆 于 2018-6-2 21:05 编辑
#include<iostream>
using namespace std;
int n,a,b;
int f[201],now[201],s[201],h,t;
int main()
{
cin>>n>>a>>b;
if(a==b)cout<<0;
else
{
for(int i=1; i<=n; i++)cin>>f[i];
h=t=1;
now[h]=a;
s[a]=0;
while(h<=t)
{
int p=now[h]+f[now[h]],
q=now[h]-f[now[h]];
if(p<=n&&!s[p])
{
t++;
now[t]=p;
s[p]=s[now[h]]+1;
}
if(q>0&&!s[q])
{
t++;
now[t]=q;
s[q]=s[now[h]]+1;
}
h++;
}
if(s[b]>0)cout<<s[b];
else cout<<-1;
}
return 0;
}
复制代码
作者:
admin
时间:
2018-6-2 21:02
#include<iostream>
#include<iomanip>
using namespace std;
const int mn=220;
int n,a,b,u[mn]; ///同题目的意思 U表示上下几层楼
int s[mn],f[mn],d[mn];
///s表示现在是第几步
///f表示爸爸是谁,从哪里来的
///d表示进队列的先后顺序
int head,tail,temp,t,i;
bool bb;
int main()
{
cin>>n>>a>>b;
if (a==b) cout<<0; ///特殊判断
else
{
for (i=1; i<=n; i++)
{
cin>>u[i];
s[i]=0;
f[i]=0;
}
head=tail=1;
d[1]=a;
s[a]=0;
f[a]=0;
bb=0;
while (tail>=head && tail<=mm-1000 && !bb)
{
temp=d[head];
t=temp+u[temp];
if (t<=n && t>=1 && s[t]==0) ///不超过范围并且曾经没有到过
{
tail++;
d[tail]=t;
s[t]=s[temp]+1;
f[t]=temp;
}
if (t==b) bb=0;
t=temp-u[temp];
if (t<=n && t>=1&& s[t]==0)
{
tail++;
d[tail]=t;
s[t]=s[temp]+1;
f[t]=temp;
}
if (t==b) bb=0;
head++;
/*cout<<"d ";
for (i=1; i<=n; i++) cout<<setw(3)<<d[i];
cout<<endl;
cout<<"s ";
for (i=1; i<=n; i++) cout<<setw(3)<<s[i];
cout<<endl;
cout<<"f ";
for (i=1; i<=n; i++) cout<<setw(3)<<f[i];
cout<<endl;
*/
}
if (s[b]==0) cout<<-1;
else cout<<s[b];
}
return 0;
}
复制代码
作者:
张笑宇
时间:
2018-6-2 21:25
bfs
#include<iostream>
using namespace std;
int n,a,b;///总楼层 起点 终点
const int mx=210;
int k[mx],d[mx],f[mx],s[mx];
int x[3]={0,1,-1},i;///f1向上 f2向下
int main()
{
cin>>n>>a>>b;
for (i=1;i<=n;i++) cin>>k[i];
if (a==b) {cout<<"0";return 0;}
int tail=1,head=1;
d[1]=a,s[a]=0,f[a]=0;
while (head<=tail)
{
int temp=d[head];
for (i=1;i<=2;i++)
{
int q=temp+x[i]*k[temp];
if (1<=q&&q<=n&&!s[q])
{
tail++;
d[tail]=q;
s[q]=s[temp]+1;
}
}
head++;
}
if (s[b]>0) cout<<s[b];
else cout<<"-1";
return 0;
}
复制代码
作者:
张笑宇
时间:
2018-6-2 21:25
dfs
#include<iostream>
using namespace std;
int n,a,b,s[210],i;
int ans=999999;
bool bb[210];
void dfs(int x,int sum)///x当前楼层 sum当前次数
{
if (x==b)
{
ans=min(ans,sum);
return;
}
else if (sum<=ans)
{
bb[x]=true;
if (x+s[x]<=n && bb[x+s[x]]==0) dfs(x+s[x],sum+1);
if (x-s[x]>=1 && bb[x-s[x]]==0) dfs(x-s[x],sum+1);
bb[x]=false;
}
}
int main()
{
cin>>n>>a>>b;
for (i=1;i<=n;i++) cin>>s[i],bb[i]=0;
dfs(a,0);
if (ans==999999)
{
cout<<"-1";
return 0;
}
cout<<ans;
return 0;
}
复制代码
作者:
胡雨菲菲
时间:
2018-6-7 14:44
#include <cstdio>
#include <queue>
const int N = 210;
int n, b, a, k[N];
bool vis[N];
struct Sta {
int floor, step;
Sta(int f, int s) {
this->floor = f;
this->step = s;
}
};
void BFS() {
std::queue<Sta> Q;
Q.push(Sta(a, 0));
vis[a] = 1;
while(!Q.empty()) {
Sta s = Q.front();
Q.pop();
if(s.floor == b) {
printf("%d", s.step);
return;
}
int p = s.floor + k[s.floor];
if(p > 0 && p <= n && !vis[p]) {
vis[p] = 1;
Q.push(Sta(p, s.step + 1));
}
p = s.floor - k[s.floor];
if(p > 0 && p <= n && !vis[p]) {
vis[p] = 1;
Q.push(Sta(p, s.step + 1));
}
}
printf("-1");
return;
}
int main() {
scanf("%d%d%d", &n, &a, &b);
for(int i = 1; i <= n; i++) {
scanf("%d", &k[i]);
}
BFS();
return 0;
}
复制代码
作者:
lyc
时间:
2018-7-2 16:52
数据小……dfs剪点枝就过了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int N = 220;
const int oo = 0x3f3f3f3f;
using namespace std;
int c[N];//楼层上的数字
int st, ed, n;
int vis[N];
int ans = oo;
void dfs(int now, int sum)
{
if(sum > ans) return ;
if(now == ed)
{
ans = min(ans, sum);
return;
}
if(now + c[now] <= n && vis[now+c[now]] == 0)
{
vis[now+c[now]] = 1;
dfs(now+c[now], sum + 1);
vis[now+c[now]] = 0;
}
if(now - c[now] >= 1 && vis[now-c[now]] == 0)
{
vis[now-c[now]] = 1;
dfs(now-c[now], sum + 1);
vis[now-c[now]] = 0;
}
}
int main()
{
cin>>n>>st>>ed;
for(int i=1; i<=n; i++)
{
cin>>c[i];
}
dfs(st, 0);
if(ans == oo)
cout<<-1;
else
cout<<ans;
return 0;
}
复制代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2