zoukankan      html  css  js  c++  java
  • 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 _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<cstring>
    #include<queue>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define EPS 1e-7
    typedef unsigned long long ll;
    const int N_MAX = 150000+10;
    const int MOD = 1e10+7;
    int n,st[N_MAX],t;//堆栈st保存当前一层所有的节点的下标
    bool vis[N_MAX];
    char a[N_MAX],ans[N_MAX],_max;
    struct Node {
        int index, step;
        Node(int index = 0, int step = 0) :index(index), step(step) {}
        bool operator < (const Node &b)const {
            if (this->step != b.step)return step > b.step;
            else return a[this->index] < a[b.index];
        }
    };
    
    void init(int &n) {
        memset(st, 0, sizeof(n));
        t = 0;
        memset(vis, 0, sizeof(vis));
        for (int i = 0; i < n; i++)ans[i] = '0'-1;
        _max = '0'-1;
    }
    
    void bfs() {
        priority_queue<Node>que;
        for (int i = 0; i < n; i++) {
            if (_max == a[i]) { que.push(Node(i, 0));  }//初始将值最大的元素节点压入队列
        }
        int pre_step = -1,t=0;
        while (!que.empty()) {
            Node p = que.top(); que.pop();
            if (pre_step != p.step) {//判断当前是第几层,如果到达新一层,之前记录销毁
                pre_step = p.step;
                while (t)vis[st[--t]] = false;
            }
            if (ans[p.step] > a[p.index] || p.step >= n || vis[p.index])continue;//如果当前的节点value比较小或者当前节点已经走过,剪枝
            ans[p.step] = a[p.index];
            st[t++] = p.index;
            vis[p.index] = true;
            que.push(Node(((ll)p.index*p.index+1)%n,p.step+1));
        }
        
    }
    
    
    
    int main() {
        int t; scanf("%d",&t);
        for (int cs = 1; cs <= t;cs++) {
            scanf("%d", &n);
            init(n);
            scanf("%s",a);
            for (int i = 0; i < n;i++) _max = max(_max, a[i]);
            bfs();
            ans[n] = '';
            printf("Case #%d: %s
    ",cs,ans);
        }
        return 0;
    }
  • 相关阅读:
    丑数系列
    452. 用最少数量的箭引爆气球
    406. 根据身高重建队列
    763. 划分字母区间
    所有二叉树题目记录
    二叉树前中后序遍历非递归(迭代)解法
    二叉树的层序遍历题目汇总
    442. 数组中重复的数据&&448. 找到所有数组中消失的数字
    225. 用队列实现栈(Easy)
    使用ClosedXML读写excel
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/9775648.html
Copyright © 2011-2022 走看看