地址:http://acm.hdu.edu.cn/showproblem.php?pid=6223
思路:BFS+剪枝。对于每一层,找其最大值mm,对于小于mm的点和找的可能为同一个点进行剪枝。
Code:
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
typedef long long LL;
const int MAX_N=150005;
int n,T;
char str[MAX_N],res[MAX_N],mx;
int e[MAX_N],dd[MAX_N];
bool boo[MAX_N];
void BFS();
int main()
{
scanf("%d",&T);
for(int t=1;t<=T;++t)
{
mx='0';
scanf("%d%s",&n,str);
LL nn=n;
for(LL i=0;i<nn;++i){
e[i]=(i*i+1)%nn;
mx=max(str[i],mx);
}
BFS();
res[n]='\0';
printf("Case #%d: %s\n",t,res);
}
return 0;
}
void BFS()
{
queue<int> Q;
for(int i=0;i<n;++i)
if(str[i]==mx) Q.push(i);
res[0]=mx;
Q.push(-1);
int ss=1,top=0;
char Max=mx,mm='0';
while(!Q.empty()&&ss<n){
int u=Q.front(); Q.pop();
if(u!=-1){
if(str[u]==Max&&mm<=str[e[u]]&&!boo[u]){
mm=str[e[u]];
Q.push(e[u]);
boo[u]=true;
dd[top++]=u;
}
}else{
Max=mm;
mm='0';
res[ss]=Max;
++ss;
Q.push(-1);
while(top>0){
boo[dd[--top]]=false;
}
}
}
}