HDU - 6223 Infinite Fraction Path

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37129433/article/details/83050440

Infinite Fraction Path
题 意:输入一个n,一个长度为n的串,串的字符都是0-9之间,下标为i的字符只能到下标为(i*i+1)%n的位置。问从从那个下标出发,能使路径字符串的字典序最大。
数据范围:
n < = 2 e 6 n<=2e6
输入样例:

4
3
149
5
12345
7
3214567
9
261025520

输出样例:

Case #1: 999
Case #2: 53123
Case #3: 7166666
Case #4: 615015015

思路:开始直接写了一发dfs,发现最差的复杂度是 n 2 n^2 头有点铁了,看题解,dfs+剪枝
+优先队列维护。优先队列每次都取第几个数step较小的一个值如果step相同就取字符较大的一个值s[index]。剪枝怎么剪呢?1.小于当前层的最大值的不需要加入队列,2.同样层,且在当前位置已经出现过了不需要加入队列。还有一个坑点,那就是必须直接算当前层,假设第一层已经知道了,然后通过第一层取算下一层。这样逻辑上是有问题的。
然后并不知道这个的复杂度是多少,玄学剪枝。欢迎留言告诉我复杂度是多少(lll¬ω¬)~

收获:这个思维还是很厉害的,要经常复习。(lll¬ω¬)

铜牌题:读题 + 思维

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<queue>
#include<cmath>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<11
#define IN freopen("input.txt","r",stdin)
#define mst(x,y) memset(x,y,sizeof(x));
#define debug(x) cout<< #x <<" = "<< (x) <<endl;
#define min(x,y) x>y?y:x
#define max(x,y) x>y?x:y
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef unsigned long long ull;
const int mod = 1e6+3;
const int INF = 0x3f3f3f3f;
const int LINF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 2e5+5;
int n;
int d[maxn];
int sta[maxn];
bool vis[maxn];
char s[maxn];
struct node {
    ll index,step;
    bool operator< (const node &_p)const {
        if(step == _p.step)return s[index]<s[_p.index];
        return step>_p.step;
    }
};
priority_queue<node> que;
void init() {
    while(!que.empty())que.pop();
    mst(d,-1);
    mst(vis,false);
    mst(sta,0);
}
int main() {
    //IN;
    int t,Kase = 1;
    scanf("%d",&t);
    while(t--) {
        init();
        scanf("%d",&n);
        scanf("%s",s);
        int len = strlen(s);
        char temp = '0';
        for(int i=0; i<len; i++)temp = max(temp,s[i]);
        for(int i=0; i<len; i++) {
            if(temp == s[i]) {
                que.push(node{(ll)i,(ll)1});
            }
        }
        ll last = 1,top = 0;
        while(!que.empty()) {
            node q = que.top();
            que.pop();
            if(q.step!=last) {
                last = q.step;
                while(top)vis[sta[--top]]=false;
            }
            int to = (q.index*q.index+1)%n;
            if(q.step>n || vis[q.index] || d[q.step]>s[q.index]-'0') continue;
            vis[q.index] = true;
            sta[top++]=q.index;
            d[q.step]=s[q.index]-'0';
            que.push(node{to,q.step+1});
        }
        printf("Case #%d: ",Kase++);
        for(int i=1; i<=n; i++) {
            printf("%d",d[i]);
        }
        printf("\n");
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_37129433/article/details/83050440
今日推荐