1. 程式人生 > >hdu6223 Infinite Fraction Path 2017沈陽區域賽G題 bfs加剪枝(好題)

hdu6223 Infinite Fraction Path 2017沈陽區域賽G題 bfs加剪枝(好題)

getc 細節 \n ret ast scrip mat tom ide

題目傳送門

題目大意:給出n座城市,每個城市都有一個0到9的val,城市的編號是從0到n-1,從i位置出發,只能走到(i*i+1)%n這個位置,從任意起點開始,每走一步都會得到一個數字,走n-1步,會得到一個長度為n的數列,輸出能得到的最大的數列(當成數字)。

思路:

一個數字肯定是最高位越大,這個數字本身就越大,所以肯定第一位要取最大值,在這一位取最大值的時候後面每一位都要盡量最大,所以想到bfs。

但是bfs肯定要剪枝,怎麽剪枝呢?

1、按照思路,我要取每一位盡可能大的值,所以某一個狀態的某一位小於我當前以及有的解,這個狀態肯定被舍棄。

這是最好想的思路,但是如果對於一個全是9的數列,這個剪枝完全沒有用,所以必須有其他的剪枝。

2、如果到了從不同起點到達某一個位置,在答案數列中的層次是一樣的,舍棄掉。(換句話說,不同起點經過相同步數到達同一座城市,那麽後續的狀態都是一樣的了,所以沒必要再走下去),

具體怎麽實現呢,一開始將數列中所有最大值所在的位置入隊,對於某一種狀態,看他的下一步是否比答案中更優或者相等(答案數組初始化為-1),如果更優或者相等則重新入隊。 對於新狀態,先檢查一下當前位置的值是不是和答案數組中當前位置的最大值相等,如果不相等,舍棄,如果相等,判斷一下有沒有狀態在相同步數的情況下已經走到這一步了,有則舍棄,沒有則更新一下,然後重復上述操作。

技術分享圖片
 1 //hdu6223  249ms
 2 #include<iostream>
 3
#include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 #include<string.h> 7 #include<sstream> 8 #include<set> 9 #include<map> 10 #include<vector> 11 #include<queue> 12 #include<stack> 13 #include<bitset> 14 #define CLR(a,b) memset(a,b,sizeof(a)) 15
using namespace std; 16 typedef long long ll; 17 inline int rd() { 18 int f=1; 19 int x=0; 20 char s=getchar(); 21 while(s<0||s>9) { 22 if(s==-)f=-1; 23 s=getchar(); 24 } 25 while(s>=0&&s<=9) { 26 x=x*10+s-0; 27 s=getchar(); 28 } 29 x*=f; 30 return x; 31 } 32 const int inf=0x3f3f3f3f; 33 const int maxn=250010; 34 int maxx,vis[maxn],tot; 35 char a[maxn],ans[maxn]; 36 ll n; 37 struct dian { 38 int step;//步數 39 ll pos;//在原數組中對應的位置 40 dian() {} 41 dian(int step,ll pos):step(step),pos(pos) {} 42 }; 43 queue<dian >q; 44 inline void bfs() { 45 dian s; 46 while(!q.empty()) { 47 s=q.front(); 48 q.pop(); 49 if(s.step==n) {//終止條件 50 continue; 51 } 52 if(a[s.pos]==ans[s.step]) {//如果相等,則代表目前的狀態是最優的 53 if(vis[s.pos]==s.step)continue;//之前已經來到過這個狀態 54 vis[s.pos]=s.step; 55 s.pos= (s.pos * s.pos + 1) % n; 56 s.step++; 57 if(a[s.pos]>=ans[s.step]) { 58 ans[s.step]=a[s.pos]; 59 q.push(s); 60 } 61 } 62 } 63 } 64 int main() { 65 int T; 66 int cas=1; 67 cin>>T; 68 while(T--) { 69 while(!q.empty())q.pop(); 70 tot=0; 71 scanf("%lld",&n); 72 maxx=0; 73 scanf("%s",a); 74 for(int i=0; i<n; i++) { 75 maxx=max(maxx,(int)a[i]); 76 } 77 for(int i=0; i<n; i++) { 78 if(a[i]==maxx) { 79 q.push(dian(1,i));//最大值入隊 80 } 81 } 82 CLR(ans,-1); 83 CLR(vis,-1); 84 ans[1]=maxx;//第一個位置先更新 85 bfs();//主要過程 86 printf("Case #%d: ",cas++); 87 ans[n+1]=\0; 88 printf("%s",ans+1); 89 printf("\n"); 90 } 91 }
View Code

寫了很久,做了很多細節優化

技術分享圖片

Infinite Fraction Path

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 2856 Accepted Submission(s): 576


Problem Description The ant Welly now dedicates himself to urban infrastructure. He came to the kingdom of numbers and solicited an audience with the king. He recounted how he had built a happy path in the kingdom of happiness. The king affirmed Welly’s talent and hoped that this talent can help him find the best infinite fraction path before the anniversary.
The kingdom has N cities numbered from 0 to N - 1 and you are given an array D[0 ... N - 1] of decimal digits (0 ≤ D[i] ≤ 9, D[i] is an integer). The destination of the only one-way road start from the i-th city is the city labelled (i2 + 1)%N.
A path beginning from the i-th city would pass through the cities u1,u2,u3, and so on consecutively. The path constructs a real number A[i], called the relevant fraction such that the integer part of it is equal to zero and its fractional part is an infinite decimal fraction with digits D[i], D[u1], D[u2], and so on.
The best infinite fraction path is the one with the largest relevant fraction

Input The input contains multiple test cases and the first line provides an integer up to 100 indicating to the total numberof test cases.
For each test case, the first line contains the integer N (1 ≤ N ≤ 150000). The second line contains an array ofdigits D, given without spaces.
The summation of N is smaller than 2000000.

Output For each test case, you should output the label of the case first. Then you are to output exactly N characters which are the first N digits of the fractional part of the largest relevant fraction.

Sample Input 4 3 149 5 12345 7 3214567 9 261025520

Sample Output Case #1: 999 Case #2: 53123 Case #3: 7166666 Case #4: 615015015

hdu6223 Infinite Fraction Path 2017沈陽區域賽G題 bfs加剪枝(好題)