• [题解][洛谷]_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;
    }

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

  • 相关阅读:
    三个心态做人做学问 沧海
    成功走职场要找准自己的"快捷键" 沧海
    免费离线下载 拂晓风起
    Hibernate 获取某个表全部记录时 奇怪现象 (重复出现某个记录) 拂晓风起
    无法读取mdb 如果连接不了ACCESS mdb文件,就尝试安装MDAC 拂晓风起
    Netbeans 使用 Hibernate 逆向工程 生成hbm和pojo 拂晓风起
    如何点击单选框 radio 后面的文字,选中单选框 拂晓风起
    Java 连接access 使用access文件 不用配置 拂晓风起
    mysql下如何执行sql脚本 拂晓风起
    Hibernate配置access Hibernate 连接 access 拂晓风起
  • 原文地址:https://www.cnblogs.com/mxxr/p/11194573.html
Copyright © 2020-2023  润新知