1. 程式人生 > >Infinite Fraction Path(HDU6223 + bfs + 剪枝)

Infinite Fraction Path(HDU6223 + bfs + 剪枝)

都是 deb print ins fin ini efi math debug

題目鏈接:

  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 }

Infinite Fraction Path(HDU6223 + bfs + 剪枝)