点此看题面

大致题意: 对于一个字符串,我们在其末尾添加一个'.',将字符串视作一个环,则可以从\(n+1\)个位置断开得到\(n+1\)个新串。现将这\(n+1\)个新串按字典序排序('.'的字典序最小),按序给出排序后每个串末位字符,求原字符串。

前言

在一家咖啡店看到这题,在纸上乱涂乱画半天,最后口胡了出来。

不过当时做法比较复杂,后来吃饭时想了想给它整理了一下,最后写出来的做法就很简洁了。

手玩

首先我们来手玩一下样例,或许能从中发现什么。

样例给出的末位字符串是"AAAC.AB"。

通过这个末尾字符串,其实题目还间接给了我们一个信息,即这个字符串显然是由".AAAABC"这七个字符构成的。

而由于它是按字典序排列的,显然首位字符就应该按次是".AAAABC"。

把它写成一个方阵形式,就是:

\[\left\{\begin{matrix}.&?&?&?&?&?&A\\A&?&?&?&?&?&A\\A&?&?&?&?&?&A\\A&?&?&?&?&?&C\\A&?&?&?&?&?&.\\B&?&?&?&?&?&A\\C&?&?&?&?&?&B\end{matrix}\right\}
\]

由于字符串成环,也就是说,在上面的每一个字符串中,首位字符在原字符串里都跟在末位字符后面。

也就是说,'.'后面是'A','A'后面是'.'或'A'或'A'或'B','B'后面是'C','C'后面是'A'。

再次因为这些字符串是按字典序排列的,所以我们可以把每种字符后面能够跟着的那些字符排个序,然后再依次填入方阵中。

于是就得到了:

\[\left\{\begin{matrix}.&A&?&?&?&?&A\\A&.&?&?&?&?&A\\A&A&?&?&?&?&A\\A&A&?&?&?&?&C\\A&B&?&?&?&?&.\\B&C&?&?&?&?&A\\C&A&?&?&?&?&B\end{matrix}\right\}
\]

上面的做法似乎给了我们点启发,于是我们就可以套路地想到:

"A."后面跟着的是'A',"AA"后面跟着的是'.'或'A',"CA"后面跟着的是'A',".A"后面跟着的是'B',"AB"后面跟着的是'C',"BC"后面跟着的是'A'。

填入方格中,就得到:

\[\left\{\begin{matrix}.&A&B&?&?&?&A\\A&.&A&?&?&?&A\\A&A&.&?&?&?&A\\A&A&A&?&?&?&C\\A&B&C&?&?&?&.\\B&C&A&?&?&?&A\\C&A&A&?&?&?&B\end{matrix}\right\}
\]

按照这样的套路,我们就可以轻松把这个矩阵填完整了,剩下的请读者自己去尝试。

而如果把这个算法用程序实现,就是\(O(n^2)\)的复杂度,已经能够得到\(60\)分的好成绩了。

优化

接下来,我们该怎么优化呢?

如果你认认真真把样例给手玩完了,你或许可以发现一个规律:对于每一个串,它总是从同一个串转移过来的。

例如上面的第一个串,它的下一个字符总是从上面的第五个串得到的。

这让我们想到,如果能够直接求出每个串的字符从哪个串转移过来,这道题似乎就做完了。

而这其实是很好求的。

具体地,首先我们把题目中给出的末位字符排序,就得到首位字符串。

然后我们把每个字符串以末位字符为第一关键字、首位字符为第二关键字、编号为第三关键字再次排序,排序完后的第\(i\)个字符串的编号所对应的原先的字符串,就是向它转移的字符串。

如果把转移看作一条边,我们只要从第一个字符串出发,沿反向边遍历一遍,每次取原先字符串(即题目中按字典序排序的字符串)的首位字符(不难发现,原先字符串的首位字符是以首位字符为关键字排序后的结果),就是答案。

至于为什么这么做,有点难以描述,实在不清楚就自己去画画图吧,应该还是比较显然、好理解的。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 200000
using namespace std;
int n,m,a[N+5];struct data
{
int H,T,p;I data(CI x=0,CI y=0,CI t=0):H(x),T(y),p(t){}
I bool operator < (Con data& o) Con {return T^o.T?T<o.T:(H^o.H?H<o.H:p<o.p);}
}s[N+5];
class FastIO
{
private:
#define FS 100000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define pc(c) (C==E&&(clear(),0),*C++=c)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
int T;char c,*A,*B,*C,*E,FI[FS],FO[FS],S[FS];
public:
I FastIO() {A=B=FI,C=FO,E=FO+FS;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
Tp I void write(Con Ty& x,Con char& y) {write(x),pc(y);}
I void clear() {fwrite(FO,1,C-FO,stdout),C=FO;}
}F;
int main()
{
RI i;for(F.read(n),F.read(m),i=1;i<=n+1;++i) F.read(a[i]),s[i].T=a[i],s[i].p=i;//读入
for(sort(a+1,a+n+2),i=1;i<=n+1;++i) s[i].H=a[i];sort(s+1,s+n+2);//排序求出首位字符,然后再次排序
i=s[1].p;W(i^1) F.write(a[i],' '),i=s[i].p;return F.clear(),0;//遍历,输出首位字符,注意第一个'.'无需输出
}

【洛谷5794】[THUSC2015] 解密运算(模拟)的更多相关文章

  1. 洛谷 P5594 【XR-4】模拟赛

    洛谷 P5594 [XR-4]模拟赛 洛谷传送门 题目描述 X 校正在进行 CSP 前的校内集训. 一共有 nn 名 OIer 参与这次集训,教练为他们精心准备了 mm 套模拟赛题. 然而,每名 OI ...

  2. 洛谷P3434 [POI2006]KRA-The Disks [模拟]

    题目传送门 KRA 题目描述 For his birthday present little Johnny has received from his parents a new plaything ...

  3. 【题解】洛谷P3952 [NOIP2017TG] 时间复杂度(模拟)

    题目来源:洛谷P3952 思路 纯模拟没啥可说的了 果然好复杂 参考了你谷一个40行代码 代码 #include<iostream> #include<cstdio> #inc ...

  4. 【洛谷】NOIP提高组模拟赛Day2【动态开节点/树状数组】【双头链表模拟】

    U41571 Agent2 题目背景 炎炎夏日还没有过去,Agent们没有一个想出去外面搞事情的.每当ENLIGHTENED总部组织活动时,人人都说有空,结果到了活动日,却一个接着一个咕咕咕了.只有不 ...

  5. 洛谷P1039 侦探推理(模拟)

    侦探推理 题目描述 明明同学最近迷上了侦探漫画<柯南>并沉醉于推理游戏之中,于是他召集了一群同学玩推理游戏.游戏的内容是这样的,明明的同学们先商量好由其中的一个人充当罪犯(在明明不知情的情 ...

  6. 洛谷P1086 花生采摘【模拟】

    题目描述 鲁宾逊先生有一只宠物猴,名叫多多.这天,他们两个正沿着乡间小路散步,突然发现路边的告示牌上贴着一张小小的纸条:“欢迎免费品尝我种的花生!――熊字”. 鲁宾逊先生和多多都很开心,因为花生正是他 ...

  7. 洛谷P4623 [COCI2012-2013#6] BUREK [模拟]

    题目传送门 BUREK 格式难调,题面就不放了. 分析: 一道比较有思维难度的模拟题. 首先我们可以想到,对于一个三角形,可以画出一个最小矩形使得这个三角形被完全包围,并且这个矩形的边平行于坐标轴(图 ...

  8. 洛谷P2556 [AHOI2002] 黑白图像压缩 [模拟]

    题目传送门 黑白图像压缩 题目描述 选修基础生物基因学的时候, 小可可在家里做了一次图像学试验. 她知道:整个图像其实就是若干个图像点(称作像素)的序列,假定序列中像素的个数总是 8 的倍数, 于是每 ...

  9. 洛谷——P1226 取余运算||快速幂

    P1226 取余运算||快速幂 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 输入格式: 三个整数b,p,k. 输出格式: 输出“b^p mod ...

随机推荐

  1. kubernetes-集群构建

    本实验参考:https://github.com/gjmzj/kubeasz kubernetes官方github地址 https://github.com/kubernetes/kubernetes ...

  2. 深入学习CSS3-flexbox布局

    学习博客:https://css-tricks.com/snippets/css/a-guide-to-flexbox/ 学习博客:http://caibaojian.com/demo/flexbox ...

  3. node+express 配置安装以及数据解析,cookie,session

    一.express安装,创建服务 (1)安装:npm install express --save(2)创建服务 server.js: const express = require('express ...

  4. linux 各目录 常用用处

    /bin : 存储常 用用户指令 /boot : 存储 核心.模块 映像等启 动用文件/dev : 存储 设备文件/etc : 存储 系统. 服 务的配置目录 与 文件/home : 存放 个人主目录 ...

  5. java8-从Lamda到方法引用和构造引用

    一方法引用概述 经过前面2章Lamda原理引入和Lamda解析,基本就会熟练使用Lamda表达式,这次我们更深入点.来了解一下方法引用. 方法引用是特定Lamda表达式的一种简写,其思路就是能替换La ...

  6. 我的chrome 智能扩展插件copier开源了!!!

    整理了下之前写的chrome-extensions-copier,分享给大家. 这个插件呢,主要用来在chrome浏览器上复制某些网站的某些特定内容,主要是用来复制代码,提高效率!(没办法,某些网站不 ...

  7. AOP框架Dora.Interception 3.0 [5]: 基于策略的拦截器注册方式

    注册拦截器旨在解决如何将拦截器应用到目标方法的问题.在我看来,针对拦截器的注册应该是明确而精准的,也就是我们提供的注册方式应该让拦截器准确地应用到期望的目标方法上,不能多也不能少.如果注册的方式过于模 ...

  8. python 多线程编程之进程和线程基础概念

    多线程编程 在多线程(multithreaded,MT)出现之前,计算机程序的执行都是由单个步骤序列组成的,该序列组合在主机的CPU中按照同步顺序执行.无论是任务本身需要按照步骤顺序执行,还是整个过程 ...

  9. python基础之字符串讲解(下)

    7.swapspace 这个命令是让大小写翻转 s = 'qwerQ' s3 = s.swapcase() print(s3) 8.title 每个隔开(特殊字符或者数字)的单词首字母大写 s = ' ...

  10. Centos7.x部署SeaFile私有网盘

    1.安装依赖环境 yum -y install wge gcc-c++ .......... 2.关闭Firewalld防火墙和SElinux systemctl stop firewalld sys ...