zoukankan      html  css  js  c++  java
  • [题解][洛谷]_U75702/P5462_X龙珠_论何为字典序

    赛时嫌麻烦,没写

    赛后自闭了,写了一下午

    题目描述

    “X龙珠”是一款益智小游戏。游戏中有 n(2|n)n(2∣n) 个编号互不相同龙珠按照给定的顺序排成一个队列,每个龙珠上面都有一个编号。每次操作时,选择并取出龙珠队列中相邻的两个龙珠,放到目标队列的末尾(目标队列最开始是空的,且这两个龙珠的前后顺序不变),然后去除原龙珠队列的空隙。反复多次,直到原龙珠队列为空。可见,因为决策不一样导致目标队列顺序不一样。现在请求出所有方案中、目标队列字典序最大的方案。只需要给出目标队列即可。

    对字典序的理解,是这道题的关键.

    我最初的想法:字典序,不就是从头比到尾吗?那就比呗!
    把数字存成字符串,每次挑字典序最大的,这样就能保证整体字典序最大
    不就是个简单的贪心吗?

    我写了一个双向链表,保存每个元素前后"龙珠"的标号,然后用STL的堆每次取最大的"龙珠"
    flag存是否在原队列

    // U75702

    #include <iostream>
    #include <vector>
    #include <queue>
    using namespace std;

    struct node {int num; int fr, to; bool flag;} nums[100001];
    struct cmpQ {bool operator()(int a, int b) {return nums[a].num < nums[b].num;}};
    priority_queue<int, vector<int>, cmpQ>pq;
    #define TOP (nums[pq.top()])
    #define NEX (nums[(nums[pq.top()]).to])
    int n;

    int main() {

        cin >> n;

        for (int i = 1; i <= n; ++i) {
             cin >> nums[i].num;
             nums[i].fr = i - 1; nums[i].to = i + 1;
             nums[i].flag = true;
             pq.push(i);
         }

        while (!pq.empty()) {
             if (TOP.flag && TOP.to <= n) {
                 cout << TOP.num << ' ' << NEX.num << ' ';
                 NEX.flag = false;
                 nums[TOP.fr].to = NEX.to;
                 nums[NEX.to].fr = TOP.fr;
             }
             pq.pop();
         }

        return 0;

    }

    可我似乎低估了出题人的心机
    ([}9WWHM1OBK0E$7})3M{$C

    我甚至重写了一遍代码以确保代码的正确性

    最后,定位到问题:何为字典序

    数学中,字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法。 这种泛化主要在于定义有序完全有序集合(通常称为字母表)的元素的序列(通常称为计算机科学中的单词)的总顺序。

    对于数字1、2、3......n的排列,不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列 12354和12345,排列12345在前,排列12354在后。按照这样的规定,5个数字的所有的排列中最前面的是12345,最后面的是 54321。

    太恶毒了

    最后的改动过只有:

    struct node {int num; int fr, to; bool flag;} nums[100001];

    然后就A了

    不过,神奇的是,dalao们的代码怎么那么短?是不是用了什么神奇的方式存链表?

    #include <cstdio>

    int n,a[100001],k[100001],x[100001],i;

    int main()
    {
         scanf("%d",&n);
         for(i=1;i<=n;++i){
             scanf("%d",&a[i]);
             k[a[i-1]]=a[i];
             x[a[i]]=a[i-1];}
         for(i=n;i>=1;--i)
             if(k[i])printf("%d %d ",i,k[i]),k[x[i]]=k[k[i]],x[k[x[i]]]=x[i],k[k[i]]=0;
         return 0;
    }

    看不懂,懒得看,给大家看看吧

  • 相关阅读:
    perf-stat
    perf原理
    ubuntu中Docker的安装与使用
    NVM相关手册及新特性理解
    #2018BIT软件工程基础#结对项目:四则运算题目生成
    #2018BIT软件工程基础#个人项目:数独
    第一篇博文:自我介绍&新学期展望
    越早明白这些道理,越能少走一些弯路
    把知识连接起来就是创意
    【翻译】24款界面精美的免费UI工具包
  • 原文地址:https://www.cnblogs.com/mxxr/p/11194573.html
Copyright © 2011-2022 走看看