hdu6223 Infinite Fraction Path 2017沈阳区域赛G题 bfs加剪枝(好题)
Posted mountaink
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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、按照思路,我要取每一位尽可能大的值,所以某一个状态的某一位小于我当前以及有的解,这个状态肯定被舍弃。
这是最好想的思路,但是如果对于一个全是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]=‘