点此看题面

大致题意: 对于一个字符串,我们在其末尾添加一个'.',将字符串视作一个环,则可以从\(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. Dubbo学习系列之七(分布式订单ID方案)

    既然选择,就注定风雨兼程! 开始吧! 准备:Idea201902/JDK11/ZK3.5.5/Gradle5.4.1/RabbitMQ3.7.13/Mysql8.0.11/Lombok0.26/Erl ...

  2. 插入排序 C&&C++

    (blog主要用于展示算法流程) 插入排序算法:通过对未排序的数据逐个插入合适的位置而完成排序工作       流程: (1)先对数组前两个数据进行从小到大排序 (2)将第三个数据与前两个数据比较,将 ...

  3. Vue底层实现原理总结

    要实现MVVM 响应式原理,要实现如下几点 1.实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者 2.实现一个指令解析器Compile,对每个元素 ...

  4. Android中实现异步轮询上传文件

    前言 前段时间要求项目中需要实现一个刷卡考勤的功能,因为涉及到上传图片文件,为加快考勤的速度,封装了一个异步轮询上传文件的帮助类 效果  先上效果图 设计思路 数据库使用的框架是GreenDao,一个 ...

  5. 面试百度、阿里、腾讯,这134道Java面试题你会多少?

    这里一共是134道Java面试题,看看你能对几道吧! 1. Java 语言有哪些特点 2. 面向对象和面向过程的区别 3. 关于 JVM JDK 和 JRE 最详细通俗的解答 4. Oracle JD ...

  6. angular6路由参数的传递与获取

    1.访问路由链接:/test/id 路由配置: {path: 'test/:id', component: TestComponent} html传参: <a href="javasc ...

  7. 《Java基础知识》Java instanceof 运算符

    java多态性带来一个问题,就是如何判断一个变量所实际引用对象的类型.这里java帮我们引入了 instanceof 运算符. instanceof运算符用来判断一个变量的所引用对象的实际类型,注意是 ...

  8. tune kubernetes eviction parameter

    Highlight 本文会介绍kubernetes中关于集群驱逐的相关参数, 合理设置驱逐速率的考虑因素, 但是不会涉及node层面资源的驱逐阈值的设置. Basic 在kubernetes中, 如果 ...

  9. Ansible自动化部署入门到进阶笔记

    目录 一.基本部署 安装Ansible Ansible配置文件 定义Inventory 使用秘钥方式连接 使用帮助 Ansible命令应用基础 二.常见模块 三.Ansible playbook 四. ...

  10. UWP 更强大的文件获取能力

    默认情况下,通用 Windows 平台 (UWP) 应用可以访问特定文件系统位置. 应用也可以通过文件选取器或通过声明功能访问其他位置. 在创建新的应用时,默认情况下你可以访问以下文件系统位置: 1. ...