題解:
對前部有相同數值進行bfs,就相當於一起走。
剪枝:
1.如果下一步是你已經走過,並且比現在的步數要高則可以去掉;
2.如果數值小於當前這步最大值也可以去掉;
3.把狀態按照步數小,數值大排序可以節省時間。
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <stack>
#include <cmath>
#include <deque>
#include <queue>
#include <list>
#include <set>
#include <map>
#define mem(a, b) memset(a, b, sizeof(a))
#define pi acos(-1)
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 150000+10;
ll Next[maxn], mark[maxn], ans[maxn];
int num[maxn];
struct node{
ll v, next, step;
node(){};
node(ll _v, ll _next, ll _step){
v = _v;
next = _next;
step = _step;
}
};
struct cmp{
bool operator() (const node &a, const node &b) const {
if(a.step == b.step){
return a.v < b.v;
}
return a.step > b.step;
}
};
priority_queue<node, vector<node>, cmp> q;
int main(){
int t, cas = 0;
scanf("%d", &t);
while(t--){
ll n;
scanf("%lld", &n);
int maxx = 0;
for(ll i = 0; i < n; i++){
scanf("%1d", &num[i]);
Next[i] = (i*i+1)%n;
maxx = max(maxx, num[i]);
mark[i] = -1;
ans[i] = -1;
}
for(int i = 0; i < n; i++){
if(num[i] == maxx){
q.push(node(maxx, i, 0));
}
}
while(!q.empty()){
node temp = q.top();
q.pop();
if(ans[temp.step] == -1){
ans[temp.step] = temp.v;
}
else if(ans[temp.step] > temp.v){
continue;
}
if(mark[temp.next] < temp.step){
mark[temp.next] = temp.step;
}
else{
continue;
}
if(temp.step == n-1){
continue;
}
q.push(node(num[Next[temp.next]], Next[temp.next], temp.step+1));
}
printf("Case #%d: ", ++cas);
for(int i = 0; i < n; i++){
printf("%d", ans[i]);
}
printf("\n");
}
}