HDU 6223 Infinite Fraction Path(BFS+剪枝)

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

InputThe 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.

OutputFor 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

跟某位大佬学的,大概不是标解,但也很有道理的样子分析:题目中让我们找最大的,那么每一层都需要保持最大。所以我们可以将第一层最大的先加入队列,然后将每一层都进行BFS找最大需要进行的剪枝是 1.如果这一层的值小于最大值就不加入队列,已经加入的直接出队              2.如果已经在该层走到过该点,那么直接不入队。通过优先队列可以将价值大和步骤多的先进行操作,就能有效的剪枝

代码如下:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
typedef long long ll;
const int MAXN=151000;
int maxx[MAXN];
int max1;
char str[MAXN];
int a[MAXN];
int t,n;
int vis[MAXN];
int num[MAXN];
ll last;
struct node
{
   int val;
   ll id;
   int step;
};
bool operator <(node A,node B)
{
    if(A.step==B.step)return A.val>B.val;
    return A.step>B.step;
}
void bfs()
{

    max1=0;
    priority_queue<node>Q;
    for(int i=0;i<n;i++)
    max1=max(max1,a[i]);
    maxx[1]=max1;
    node a1,next1;
    for(int i=0;i<n;i++)
    {
        if(a[i]==max1)
          {
              a1.id=i;
              a1.val=a[i];
              a1.step=1;
              Q.push(a1);
          }
    }
    last=0;
    int top=0;
    while(!Q.empty())
    {
       a1=Q.top();
       Q.pop();
       if(last<a1.step)
       {
          last=a1.step;
          while(top)vis[num[--top]]=0;
       }
       if(a1.val<maxx[a1.step]||a1.step>=n||vis[a1.id]==1)
       continue;
       num[top]=a1.id;
       vis[num[top++]]=1;
       next1.id=(a1.id*a1.id+1)%n;
       next1.val=a[next1.id];
       next1.step=a1.step+1;
       if(next1.val>=maxx[next1.step])
       {
          maxx[next1.step]=next1.val;
          Q.push(next1);
       }
    }
}
int main()
{
    int Case=0;
     scanf("%d",&t);
     while(t--)
     {
         Case++;
        memset(maxx,0,sizeof(maxx));
        scanf("%d",&n);
        scanf("%s",str);
        for(int i=0;i<n;i++)
        a[i]=str[i]-‘0‘;
        bfs();
        printf("Case #%d: ",Case);
        for(int i=1;i<=n;i++)
        printf("%d",maxx[i]);
        printf("\n");
     }
    return 0;
}
				
时间: 2024-08-13 21:49:10

HDU 6223 Infinite Fraction Path(BFS+剪枝)的相关文章

hdu 6223 Infinite Fraction Path

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6223 题意:给定长度为n的一串数字S,现在要按照一种规则寻找长度为n的数字串,使得该数字串的字典序最大.规则:从数字串S的某一个下标为x的数字出发,可以到达的下一个数字是下标为(x*x+1)%n的数字. 思路:BFS+剪枝.剪枝技巧: 1:遍历到某一层的节点时,记录已经到达过的节点,下次如果还经过就直接不考虑. 2:当前遍历到的某一层节点的数字较之前的小,直接不考虑. AC代码: #define _

hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)

题目传送门 题目大意:给出n座城市,每个城市都有一个0到9的val,城市的编号是从0到n-1,从i位置出发,只能走到(i*i+1)%n这个位置,从任意起点开始,每走一步都会得到一个数字,走n-1步,会得到一个长度为n的数列,输出能得到的最大的数列(当成数字). 思路: 一个数字肯定是最高位越大,这个数字本身就越大,所以肯定第一位要取最大值,在这一位取最大值的时候后面每一位都要尽量最大,所以想到bfs. 但是bfs肯定要剪枝,怎么剪枝呢? 1.按照思路,我要取每一位尽可能大的值,所以某一个状态的某

HDU6223——2017ICPC徐州G Infinite Fraction Path

题意: 给定一个数字串,每个位子都能向(i*i+1)%n的位子转移,输出路径上,字典序最大的,长度为n的串. 参考:https://www.cnblogs.com/mountaink/p/9541442.html 思路: BFS, 一个数字肯定是最高位越大,这个数字本身就越大,所以肯定第一位要取最大值,在这一位取最大值的时候后面每一位都要尽量最大,所以想到bfs. 但是bfs肯定要剪枝,怎么剪枝呢? 1.按照思路,我要取每一位尽可能大的值,所以某一个状态的某一位小于我当前以及有的解,这个状态肯定

ACM-ICPC 2017 沈阳赛区现场赛 G. Infinite Fraction Path &amp;&amp; HDU 6223

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6223 参考题解:https://blog.csdn.net/qq_40482495/article/details/78492841 注意优先队列自定义比较级的用法!! 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define

codeforces 1072D Minimum path bfs+剪枝 好题

题目传送门 题目大意: 给出一幅n*n的字符,从1,1位置走到n,n,会得到一个字符串,你有k次机会改变某一个字符(变成a),求字典序最小的路径. 题解: (先吐槽一句,cf 标签是dfs题????) 这道题又学到了,首先会发现,从原点出发,走x步,所有的情况都是在一条斜线上的,而再走一步就是下一条斜线.所以用两个队列进行bfs(把当前步和下一步要处理的字符分开). 到了这里思路就明朗了,每次走的时候如果本身的map里是a就直接走,不是a就看k是否大于0,再看这个字符是不是比答案串里对应位置的字

POJ 3126 Prime Path (BFS+剪枝)

题目链接:传送门 题意: 给定两个四位数a,b,每次可以改变a的任意一位,并且确保改变后的a是一个素数. 问最少经过多少次改变a可以变成b. 分析: BFS,每次枚举改变的数,有一个剪枝,就是如果这个改变的数之前已经得到过了, 就没有必要继续变回它了. 代码如下: #include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <queue&g

【HDOJ6223】Infinite Fraction Path(后缀数组)

题意: 给一个长度为n的字符串s[0..n-1],但i的后继不再是i+1,而是(i*i+1)%n,求所有长度为n的"子串"中,字典序最大的是谁 n<=150000,s[i]=0..9 思路:后缀数组 因为前驱与后继的关系已经变化,就不能用下标直接加减 i的后继是唯一的,i的前驱却不一定 所以对于后继使用倍增,对于前驱每个位置暴力开队列存储,需要的时候再拿出来 在判断的地方稍作修改 1 #include<cstdio> 2 #include<cstring>

HDU6223 &amp;&amp; 2017沈阳ICPC: G. Infinite Fraction Path——特殊图&amp;&amp;暴力

题意 给定一个数字串,每个位子都能向(i*i+1)%n的位子转移,输出在路径上.字典序最大的.长度为n的串($n \leq 150000$). 分析 先考虑一个暴力的方法,考虑暴力每个x,然后O(n)判定形成的字符串字典序是否比当前的最优解要大,复杂度O(n²),显然大家都会做. 而本题中有个结论:没有必要每次O(n),只要前100个字符一样,那么后面的一定都一样!所以>500直接break,复杂度O(500n), 可以过! 理解:对于所有的下标k,k向(k*k+1)%n连一条有向边,最后可以得

hdu 1728 逃离迷宫 (BFS)

逃离迷宫 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14376    Accepted Submission(s): 3458 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方