2017沈阳区域赛Infinite Fraction Path(BFS + 剪枝)

Infinite Fraction Path

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


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
 

 

Source
 

 

Recommend
jiangzijing2015   |   We have carefully selected several similar problems for you:   6730  6729  6728  6727  6726 
 
这题要注意的细节还是有点多的,算是比较细腻处理的bfs的题目了.
 1 /*************************************************************************
 2     > File Name: hdu-6223.infinite_fraction_path.cpp
 3     > Author: CruelKing
 4     > Mail: 2016586625@qq.com 
 5     > Created Time: 2019年09月18日 星期三 15时57分37秒
 6     本题思路:BFS暴力,先找出最大的几个数的位置,接着bfs每次寻找下一层最大的值,直到
 7     找到答案为止.
 8     注意剪枝:1.如果在当前层寻找到了比最大值小的值直接pop.
 9              2.如果当前层有多个结点通往下一层的同一个结点,只需要保留一个就行了.
10  ************************************************************************/
11 
12 #include <cstdio>
13 #include <queue>
14 #include <cstring>
15 using namespace std;
16 
17 typedef long long ll;
18 
19 const int maxn = 150000 + 5;
20 char str[maxn], ans[maxn];
21 
22 int M[maxn], tot;
23 bool vis[maxn];
24 
25 int n;
26 
27 ll sta[maxn], top;
28 
29 struct node {
30     ll index, step;
31 };
32 
33 bool operator < (node a, node b) {
34     if(a.step == b.step) return str[a.index] < str[b.index];
35     return a.step > b.step;
36 }
37 
38 void bfs() {
39     priority_queue <node> que;
40     for(int i = 0; i < tot; i ++) {
41         que.push((node) {M[i], 0});//最大值入队列
42     }
43     ll last = 0;
44     while(!que.empty()) {
45         node now = que.top();
46         que.pop();
47         if(last != now.step) {
48             last = now.step;
49             while(top) vis[sta[-- top]] = false;//把当前标记过得结点都释放,因为他们还可以继续访问
50         }
51         if(ans[now.step] > str[now.index] || now.step >= n || vis[now.index]) continue;//如果在当前层当前位置已经被访问过了就跳过这个结点, 如果当前已经找到了n个数就跳过这个结点,如果已经当前结点字典序小于之前访问过的最大值就跳过这个结点
52         sta[top ++] = now.index;//把当前访问的结点放入队列并标记
53         vis[now.index] = true;
54         ans[now.step] = str[now.index];//更新答案
55         que.push((node) {(now.index * now.index + 1) % n, now.step + 1});//跳跃
56     }
57     while(top) vis[sta[-- top]] = false;
58     ans[n] = '\0';
59 }    
60 
61 int _case;
62 
63 void print() {
64     printf("Case #%d: %s\n", ++_case, ans);
65 }
66 
67 int main() {
68     int t, _case = 0;
69     int Max;
70     char k;
71     scanf("%d", &t);
72     while(t --) {
73         for(int i = 0; i < n; i ++) ans[i] = 0;
74         k = 0;
75         tot = 0;
76         scanf("%d", &n);
77         scanf("%s", str);
78         for(int i = 0; i < n; i ++) {
79             if(str[i] > k) {
80                 k = str[i];
81             }
82         }
83         for(int i = 0; i < n; i ++) {
84             if(str[i] == k) {
85                 M[tot ++] = i;//存储字符串中的最大值
86             }
87         }
88         bfs();
89         print();
90     }
91     return 0;
92 }

 

转载于:https://www.cnblogs.com/bianjunting/p/11544100.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值