Infinite Fraction Path(HDU6223 + bfs + 剪枝)

题目链接:

  http://acm.hdu.edu.cn/showproblem.php?pid=6223

题目:

题意:

  给你一个长度为n的数字串,开始时你选择一个位置(记为i,下标从0开始)做为起点,那么下一步将在(i × i + 1)%n处,将字典序最大的路径上的数打印出来。

思路:

  要想字典序最大,那么只需每一步都是最大的即可。由题意可知,当起点确定时,所对应的数也就确定了。对于每一步,我们只需当前为最优即可,若第i步有t种方式使得当前数为x,那么下一步也将会有t种选择,那么我们可以用优先队列维护下一步的最优值(具体看代码。这题不加剪枝会T,由于操作中有取膜操作,那么对于同一步,取膜后的下一个位置极有可能会相同,也就是同一个位置重复入队列,这样后面的步骤都会重复,这样复杂度将会增大数倍,此时我们可以用一个set去重,防止同一步重复入队列。

代码实现如下:

  1 #include <set>
  2 #include <map>
  3 #include <deque>
  4 #include <ctime>
  5 #include <stack>
  6 #include <cmath>
  7 #include <queue>
  8 #include <string>
  9 #include <cstdio>
 10 #include <vector>
 11 #include <iomanip>
 12 #include <cstring>
 13 #include <iostream>
 14 #include <algorithm>
 15 using namespace std;
 16 
 17 typedef long long LL;
 18 typedef pair<LL, LL> pll;
 19 typedef pair<LL, int> pli;
 20 typedef pair<int, int> pii;
 21 typedef unsigned long long uLL;
 22 
 23 #define lson rt<<1
 24 #define rson rt<<1|1
 25 #define name2str(name)(#name)
 26 #define bug printf("**********\n");
 27 #define IO ios::sync_with_stdio(false);
 28 #define debug(x) cout<<#x<<"=["<<x<<"]"<<endl;
 29 #define FIN freopen("/home/dillonh/code/OJ/in.txt","r",stdin);
 30 
 31 const double eps = 1e-8;
 32 const int mod = 1e9 + 7;
 33 const int maxn = 2000000 + 7;
 34 const int inf = 0x3f3f3f3f;
 35 const double pi = acos(-1.0);
 36 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
 37 
 38 int T, n;
 39 int t[maxn];
 40 char s[maxn];
 41 
 42 struct node {
 43     int id, val, step;
 44     bool operator < (const node& x) const {
 45         return step == x.step ? val < x.val : step > x.step;
 46     }
 47 }nw, nxt;
 48 
 49 set<int> stc;
 50 priority_queue<node> q;
 51 
 52 void bfs() {
 53     stc.clear();
 54     while(!q.empty()) q.pop();
 55     int mx = -1;
 56     for(int i = 0; i < n; i++) {
 57         if(s[i] - '0' > mx) mx = max(mx, s[i] - '0');
 58     }
 59     for(int i = 0; i < n; i++) {  //将可能的起点压入队列中
 60         if(s[i] - '0' == mx) {
 61             nw.id = i;
 62             nw.val = mx;
 63             nw.step = 0;
 64             q.push(nw);
 65         }
 66     }
 67     int pp = 0;
 68     while(!q.empty()) {
 69         nw = q.top(); q.pop();
 70         if(nw.step >= n) return; //满足条件即可返回
 71         if(nw.step == pp + 1) {
 72             stc.clear(); //到了新的一步需将set清空
 73             mx = nw.val;
 74             pp = nw.step;
 75         }
 76         if(nw.val == mx) {
 77             t[nw.step] = nw.val;
 78             nxt.id = (1LL * nw.id * nw.id + 1) % n;
 79             if(stc.count(nxt.id)) continue; //这个位置已经被压入过队列就不需要重复压入了
 80             stc.insert(nxt.id);
 81             nxt.val = s[nxt.id] - '0';
 82             nxt.step = nw.step + 1;
 83             q.push(nxt);
 84         }
 85     }
 86 }
 87 
 88 int main() {
 89 #ifndef ONLINE_JUDGE
 90     FIN;
 91 #endif
 92     scanf("%d", &T);
 93     for(int icase = 1; icase <= T; icase++) {
 94         scanf("%d", &n);
 95         scanf("%s", s);
 96         bfs();
 97         printf("Case #%d: ", icase);
 98         for(int i = 0; i < n; i++) {
 99             printf("%d", t[i]);
100         }
101         printf("\n");
102 #ifndef ONLINE_JUDGE
103         cout <<"It costs " <<clock() <<"ms\n";
104 #endif
105     }
106     return 0;
107 }

 

posted @ 2018-10-13 20:58  Dillonh  阅读(256)  评论(0编辑  收藏  举报