Infinite Fraction Path(HDU6223 + bfs + 剪枝)

題目連接:php

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

題目:ios

題意:spa

  給你一個長度爲n的數字串,開始時你選擇一個位置(記爲i,下標從0開始)作爲起點,那麼下一步將在(i × i + 1)%n處,將字典序最大的路徑上的數打印出來。debug

思路:code

  要想字典序最大,那麼只需每一步都是最大的便可。由題意可知,當起點肯定時,所對應的數也就肯定了。對於每一步,咱們只需當前爲最優便可,若第i步有t種方式使得當前數爲x,那麼下一步也將會有t種選擇,那麼咱們能夠用優先隊列維護下一步的最優值(具體看代碼。這題不加剪枝會T,因爲操做中有取膜操做,那麼對於同一步,取膜後的下一個位置極有可能會相同,也就是同一個位置重複入隊列,這樣後面的步驟都會重複,這樣複雜度將會增大數倍,此時咱們能夠用一個set去重,防止同一步重複入隊列。blog

代碼實現以下:隊列

  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 }
相關文章
相關標籤/搜索