• Gym


    题目链接:http://codeforces.com/gym/101147/problem/E


    题意:当人在第i个商店时,他可以向左或向右跳di段距离到达另一个商店(在范围之内),一个商店为一段距离。问:对于每一个商店,跳到最后一个商店最少需要跳几次?

    题解:题目实际上是求最短距离,而且边权为1,所以可以直接用bfs。由于是求每个点到最后一个点的最短距离,那么可以反向建图,将最后一个点设为起始点,然后向前跑。对于跑不到的点,回到题目上说,实际就是这个商店不能到达最后一个商店。


    代码如下:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <string>
      6 #include <vector>
      7 #include <map>
      8 #include <set>
      9 #include <queue>
     10 #include <sstream>
     11 #include <algorithm>
     12 using namespace std;
     13 #define pb push_back
     14 #define mp make_pair
     15 #define ms(a, b)  memset((a), (b), sizeof(a))
     16 //#define LOCAL
     17 #define eps 0.0000001
     18 typedef long long LL;
     19 const int inf = 0x3f3f3f3f;
     20 const int maxn = 100000+10;
     21 const int mod = 1000000007;
     22 
     23 vector <int > v[maxn];
     24 LL len[maxn];
     25 
     26 struct node
     27 {
     28     int  sta;
     29     LL  k;
     30 };
     31 queue<node>q;
     32 node now, e;
     33 
     34 int vis[maxn];
     35 int bfs(int be)
     36 {
     37     ms(vis,0);
     38     while(!q.empty())
     39         q.pop();
     40 
     41     now.sta = be;
     42     now.k = 0;
     43     vis[be] = 1;
     44     q.push(now);
     45     len[be] = 0;
     46     while(!q.empty())
     47     {
     48         now = q.front();
     49         q.pop();
     50 
     51         int big = v[now.sta].size();
     52         for(int i = 0; i<big; i++)
     53         {
     54             if(!vis[ v[now.sta][i] ])
     55             {
     56                 e.sta = v[now.sta][i] ;
     57                 e.k = now.k+1;
     58                 len[e.sta] = e.k;
     59                 
     60                 vis[e.sta ] = 1;
     61                 q.push(e);
     62             }
     63         }
     64     }
     65     return 0;
     66 }
     67 
     68 void solve()
     69 {
     70     int n;
     71     scanf("%d", &n);
     72     for(int i = 1; i<=n; i++)
     73         v[i].clear();
     74     for(int i=1;i<=n;i++)
     75     {
     76         int d;
     77         scanf("%d", &d);
     78         if(i-d>=1)  v[i-d].pb(i);//反向建图
     79         if(i+d<=n)  v[i+d].pb(i);
     80     }
     81 
     82     ms(len,-1);
     83     bfs(n);
     84     for(int i = 1; i<=n; i++)
     85         printf("%lld
    ",len[i]);
     86 }
     87 
     88 int main()
     89 {
     90     #ifdef LOCAL
     91          freopen("jumping.in", "r", stdin);
     92 //      freopen("output.txt", "w", stdout);
     93     #endif // LOCAL
     94 
     95     int T;
     96     scanf("%d", &T);
     97     while(T--){
     98         solve();
     99     }
    100 
    101     return 0;
    102 }
    View Code


  • 相关阅读:
    mongodb进阶三之mongodb管理
    《Javascript权威指南》学习笔记之十九--HTML5 DOM新标准---处理文档元信息和管理交互能力
    TCP/IP协议族-----21、文件传送:FTP和TFTP
    Leetcode Two Sum
    MongoDB 操作手冊CRUD 删除 remove
    VSync Count 垂直同步
    机器学习实战笔记1(机器学习基础)
    Cacti监控MySQL实现过程中碰到的问题解汇总
    【LeetCode】- Search Insert Position(查找插入的位置)
    去除百度推广的广告
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538725.html
Copyright © 2020-2023  润新知