华师一附中OI组

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1826|回复: 7
打印 上一主题 下一主题

P1135 奇怪的电梯

[复制链接]

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
跳转到指定楼层
楼主
发表于 2018-5-12 22:22:26 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
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
回复

使用道具 举报

1

主题

15

帖子

101

积分

注册会员

Rank: 2

积分
101
8#
发表于 2018-7-2 16:52:55 | 只看该作者
数据小……dfs剪点枝就过了
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. const int N = 220;
  6. const int oo = 0x3f3f3f3f;
  7. using namespace std;
  8. int c[N];//楼层上的数字
  9. int st, ed, n;
  10. int vis[N];
  11. int ans = oo;
  12. void dfs(int now, int sum)
  13. {
  14.     if(sum > ans) return ;
  15.     if(now == ed)
  16.     {
  17.         ans = min(ans, sum);
  18.         return;
  19.     }
  20.     if(now + c[now] <= n && vis[now+c[now]] == 0)
  21.     {
  22.         vis[now+c[now]] = 1;
  23.         dfs(now+c[now], sum + 1);
  24.         vis[now+c[now]] = 0;
  25.     }
  26.     if(now - c[now] >= 1 && vis[now-c[now]] == 0)
  27.     {
  28.         vis[now-c[now]] = 1;
  29.         dfs(now-c[now], sum + 1);
  30.         vis[now-c[now]] = 0;
  31.     }
  32. }
  33. int main()
  34. {
  35.     cin>>n>>st>>ed;
  36.     for(int i=1; i<=n; i++)
  37.     {
  38.         cin>>c[i];
  39.     }
  40.     dfs(st, 0);
  41.     if(ans == oo)
  42.         cout<<-1;
  43.     else
  44.         cout<<ans;
  45.     return 0;
  46. }
复制代码
回复 支持 反对

使用道具 举报

7

主题

27

帖子

91

积分

注册会员

Rank: 2

积分
91
7#
发表于 2018-6-7 14:44:47 | 只看该作者
  1. #include <cstdio>
  2. #include <queue>
  3. const int N = 210;

  4. int n, b, a, k[N];
  5. bool vis[N];

  6. struct Sta {
  7.     int floor, step;
  8.     Sta(int f, int s) {
  9.         this->floor = f;
  10.         this->step = s;
  11.     }
  12. };


  13. void BFS() {
  14.     std::queue<Sta> Q;
  15.     Q.push(Sta(a, 0));
  16.     vis[a] = 1;
  17.     while(!Q.empty()) {
  18.         Sta s = Q.front();
  19.         Q.pop();
  20.         if(s.floor == b) {
  21.             printf("%d", s.step);
  22.             return;
  23.         }
  24.         int p = s.floor + k[s.floor];
  25.         if(p > 0 && p <= n && !vis[p]) {
  26.             vis[p] = 1;
  27.             Q.push(Sta(p, s.step + 1));
  28.         }
  29.         p = s.floor - k[s.floor];
  30.         if(p > 0 && p <= n && !vis[p]) {
  31.             vis[p] = 1;
  32.             Q.push(Sta(p, s.step + 1));
  33.         }
  34.     }
  35.     printf("-1");
  36.     return;
  37. }

  38. int main() {
  39.     scanf("%d%d%d", &n, &a, &b);

  40.     for(int i = 1; i <= n; i++) {
  41.         scanf("%d", &k[i]);
  42.     }

  43.     BFS();

  44.     return 0;
  45. }
复制代码
回复 支持 反对

使用道具 举报

9

主题

89

帖子

292

积分

华一学生

积分
292
6#
发表于 2018-6-2 21:25:59 | 只看该作者
dfs
  1. #include<iostream>
  2. using namespace std;
  3. int n,a,b,s[210],i;
  4. int ans=999999;
  5. bool bb[210];
  6. void dfs(int x,int sum)///x当前楼层 sum当前次数
  7. {
  8.         if (x==b)
  9.         {
  10.                 ans=min(ans,sum);
  11.                 return;
  12.         }
  13.         else if (sum<=ans)
  14.         {
  15.                 bb[x]=true;
  16.                 if (x+s[x]<=n && bb[x+s[x]]==0) dfs(x+s[x],sum+1);
  17.                 if (x-s[x]>=1 && bb[x-s[x]]==0) dfs(x-s[x],sum+1);
  18.                 bb[x]=false;
  19.         }
  20. }
  21. int main()
  22. {
  23.         cin>>n>>a>>b;
  24.         for (i=1;i<=n;i++) cin>>s[i],bb[i]=0;
  25.         dfs(a,0);
  26.         if (ans==999999)
  27.         {
  28.                 cout<<"-1";
  29.                 return 0;
  30.         }
  31.         cout<<ans;
  32.         return 0;
  33. }
复制代码
回复 支持 反对

使用道具 举报

9

主题

89

帖子

292

积分

华一学生

积分
292
5#
发表于 2018-6-2 21:25:00 | 只看该作者
bfs
  1. #include<iostream>
  2. using namespace std;
  3. int n,a,b;///总楼层 起点 终点
  4. const int mx=210;
  5. int k[mx],d[mx],f[mx],s[mx];
  6. int x[3]={0,1,-1},i;///f1向上 f2向下
  7. int main()
  8. {
  9.     cin>>n>>a>>b;
  10.     for (i=1;i<=n;i++) cin>>k[i];
  11.     if (a==b) {cout<<"0";return 0;}
  12.     int tail=1,head=1;
  13.     d[1]=a,s[a]=0,f[a]=0;
  14.     while (head<=tail)
  15.     {
  16.         int temp=d[head];
  17.         for (i=1;i<=2;i++)
  18.         {
  19.             int q=temp+x[i]*k[temp];
  20.             if (1<=q&&q<=n&&!s[q])
  21.             {
  22.                 tail++;
  23.                 d[tail]=q;
  24.                 s[q]=s[temp]+1;
  25.             }
  26.         }
  27.         head++;
  28.     }
  29.     if (s[b]>0) cout<<s[b];
  30.     else cout<<"-1";
  31.     return 0;
  32. }
复制代码
回复 支持 反对

使用道具 举报

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
地板
 楼主| 发表于 2018-6-2 21:02:56 | 只看该作者
  1. #include<iostream>
  2. #include<iomanip>
  3. using namespace std;
  4. const int mn=220;
  5. int n,a,b,u[mn]; ///同题目的意思 U表示上下几层楼
  6. int s[mn],f[mn],d[mn];
  7. ///s表示现在是第几步
  8. ///f表示爸爸是谁,从哪里来的
  9. ///d表示进队列的先后顺序

  10. int head,tail,temp,t,i;
  11. bool bb;
  12. int main()
  13. {
  14.     cin>>n>>a>>b;
  15.     if (a==b) cout<<0;  ///特殊判断
  16.     else
  17.     {
  18.         for (i=1; i<=n; i++)
  19.         {
  20.             cin>>u[i];
  21.             s[i]=0;
  22.             f[i]=0;
  23.         }
  24.         head=tail=1;
  25.         d[1]=a;
  26.         s[a]=0;
  27.         f[a]=0;
  28.         bb=0;
  29.         while (tail>=head  &&  tail<=mm-1000 && !bb)
  30.         {
  31.             temp=d[head];
  32.             t=temp+u[temp];
  33.             if (t<=n && t>=1 && s[t]==0)   ///不超过范围并且曾经没有到过
  34.             {
  35.                 tail++;
  36.                 d[tail]=t;
  37.                 s[t]=s[temp]+1;
  38.                 f[t]=temp;

  39.             }
  40.             if (t==b) bb=0;
  41.             t=temp-u[temp];
  42.             if (t<=n && t>=1&& s[t]==0)
  43.             {
  44.                 tail++;
  45.                 d[tail]=t;
  46.                 s[t]=s[temp]+1;
  47.                 f[t]=temp;
  48.             }
  49.             if (t==b) bb=0;
  50.             head++;

  51.             /*cout<<"d ";
  52.             for (i=1; i<=n; i++) cout<<setw(3)<<d[i];
  53.             cout<<endl;
  54.             cout<<"s ";
  55.             for (i=1; i<=n; i++) cout<<setw(3)<<s[i];
  56.             cout<<endl;
  57.             cout<<"f ";
  58.             for (i=1; i<=n; i++) cout<<setw(3)<<f[i];
  59.             cout<<endl;
  60.             */
  61.         }
  62.         if (s[b]==0) cout<<-1;
  63.         else cout<<s[b];
  64.     }
  65.     return 0;
  66. }
复制代码
回复 支持 反对

使用道具 举报

9

主题

158

帖子

470

积分

华一学生

积分
470
QQ
板凳
发表于 2018-6-2 20:51:44 | 只看该作者
本帖最后由 黄煦喆 于 2018-6-2 21:05 编辑
  1. #include<iostream>
  2. using namespace std;
  3. int n,a,b;
  4. int f[201],now[201],s[201],h,t;
  5. int main()
  6. {
  7.     cin>>n>>a>>b;
  8.     if(a==b)cout<<0;
  9.     else
  10.     {
  11.         for(int i=1; i<=n; i++)cin>>f[i];
  12.         h=t=1;
  13.         now[h]=a;
  14.         s[a]=0;
  15.         while(h<=t)
  16.         {
  17.             int p=now[h]+f[now[h]],
  18.                 q=now[h]-f[now[h]];
  19.             if(p<=n&&!s[p])
  20.             {
  21.                 t++;
  22.                 now[t]=p;
  23.                 s[p]=s[now[h]]+1;
  24.             }
  25.             if(q>0&&!s[q])
  26.             {
  27.                 t++;
  28.                 now[t]=q;
  29.                 s[q]=s[now[h]]+1;
  30.             }
  31.             h++;
  32.         }
  33.         if(s[b]>0)cout<<s[b];
  34.         else cout<<-1;
  35.     }
  36.     return 0;
  37. }
复制代码

回复 支持 反对

使用道具 举报

738

主题

1485

帖子

5422

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5422
沙发
 楼主| 发表于 2018-5-12 22:23:30 | 只看该作者
裸的BFS 当然也可以dijistra 其实所有的边长为1的时候 Dijistra不就是BFS吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|服务支持:DZ动力|华师一附中OI组  

GMT+8, 2024-12-26 13:40 , Processed in 0.141863 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表