1692: [Usaco2007 Dec]队列变换

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1756  Solved: 737
[Submit][Status][Discuss]

Description

FJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的“全美农场主大奖赛”。在这场比赛中,每个参赛者都必须让他的奶牛排成一列,然后领她们从裁判席前依次走过。 今年,竞赛委员会在接受队伍报名时,采用了一种新的登记规则:他们把所有队伍中奶牛名字的首字母取出,按它们对应奶牛在队伍中的次序排成一列(比如说,如果FJ带去的奶牛依次为Bessie、Sylvia、Dora,登记人员就把这支队伍登记为BSD)。登记结束后,组委会将所有队伍的登记名称按字典序升序排列,就得到了他们的出场顺序。 FJ最近有一大堆事情,因此他不打算在这个比赛上浪费过多的时间,也就是说,他想尽可能早地出场。于是,他打算把奶牛们预先设计好的队型重新调整一下。 FJ的调整方法是这样的:每次,他在原来队列的首端或是尾端牵出一头奶牛,把她安排到新队列的尾部,然后对剩余的奶牛队列重复以上的操作,直到所有奶牛都被插到了新的队列里。这样得到的队列,就是FJ拉去登记的最终的奶牛队列。 接下来的事情就交给你了:对于给定的奶牛们的初始位置,计算出按照FJ的调整规则所可能得到的字典序最小的队列。

Input

* 第1行: 一个整数:N

* 第2..N+1行: 第i+1行仅有1个'A'..'Z'中的字母,表示队列中从前往后数第i 头奶牛名字的首字母

Output

* 第1..??行: 输出FJ所能得到的字典序最小的队列。每行(除了最后一行)输 出恰好80个'A'..'Z'中的字母,表示新队列中每头奶牛姓名的首 字母

Sample Input

6
ACDBCB

Sample Output

ABCBCD

有个很明显的贪心思路:

如果把当前串反过来之后字典序会变大,那么说明当前应该选择开头的字符

如果把当前串反过来之后字典序会变小,那么说明当前应该选择结尾的字符

因为每选一个字符之后当前串就变了,暴力算字典序是不可能的,复杂度n²

所以要①将原串反过来接到自身后面,②用后缀数组预处理每个可能串的字典序大小

例如ACDBCB:ACDBCBBCBDCA(步骤①)

rank[] = 2 10 11 4 8 3 5 9 6 12 7 1(步骤②)

p                     q

第三步:用两个指针p和q遍历,如果当前rank[p]<rank[q],输出p位置的字符,p++,q同理

输完n个字符之后结束

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
char str[80100];
int a[80100], Rank[80100], Temp[80100], cot[80100], Sa[80100];
int main(void)
{int n, i, m, p, q, k;while(scanf("%d", &n)!=EOF){for(i=1;i<=n;i++)scanf(" %c", &str[i]);str[2*n+2] = 0;for(i=n+1;i<=2*n;i++)str[i] = str[2*n-i+1];n *= 2;for(i=1;i<=n;i++)a[i] = str[i];m = 128;memset(cot, 0, sizeof(cot));for(i=1;i<=n;i++){Rank[i] = a[i];cot[a[i]]++;}for(i=1;i<=m;i++)cot[i] += cot[i-1];for(i=n;i>=1;i--)Sa[cot[a[i]]--] = i;for(k=1;k<=n;k*=2){p = 0;for(i=n-k+1;i<=n;i++)Temp[++p] = i;for(i=1;i<=n;i++){if(Sa[i]>k)Temp[++p] = Sa[i]-k;}memset(cot, 0, sizeof(cot));for(i=1;i<=n;i++)cot[Rank[i]]++;for(i=1;i<=m;i++)cot[i] += cot[i-1];for(i=n;i>=1;i--)Sa[cot[Rank[Temp[i]]]--] = Temp[i];swap(Rank, Temp);p = 1;Rank[Sa[1]] = 1;for(i=2;i<=n;i++){if(Temp[Sa[i-1]]==Temp[Sa[i]] && Temp[Sa[i-1]+k]==Temp[Sa[i]+k])Rank[Sa[i]] = p;elseRank[Sa[i]] = ++p;}m = p;}n /= 2;p = 1, q = n+1;for(i=1;i<=n;i++){if(Rank[p]<Rank[q])printf("%c", str[p++]);elseprintf("%c", str[q++]);if(i%80==0)printf("\n");}printf("\n");}
}

bzoj 1640 bzoj 1692: [Usaco2007 Dec]队列变换(后缀数组)相关推荐

  1. BZOJ 1692: [Usaco2007 Dec]队列变换( 贪心 )

    数据 n <= 30000 , 然后 O( n² ) 的贪心也过了..... USACO 数据是有多弱啊 = = ( ps : BZOJ 1640 和此题一模一样 , 双倍经验 ) ------ ...

  2. bzoj:1692 [Usaco2007 Dec]队列变换1640 [Usaco2007 Nov]Best Cow Line 队列变换

    Description FJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的"全美农场主大奖赛".在这场比赛中,每个参赛者都必须让他的奶牛排成一列 ...

  3. 【BZOJ】1692: [Usaco2007 Dec]队列变换

    [算法]字符串hash [题解] 显然如果字母互不相同,贪心取是正确的. 如果存在字母相同,那么就换成比较后缀和前缀嘛. 但是要注意,不是后缀和前缀相同就能直接跳跃,每次必须只推一位. 取模的哈希比自 ...

  4. UOJ #219 BZOJ 4650 luogu P1117 [NOI2016]优秀的拆分 (后缀数组、ST表)

    UOJ #219 BZOJ 4650 luogu P1117 [NOI2016]优秀的拆分 (后缀数组.ST表) 连NOI Day1T1都不会做...看了题解都写不出来还要抄Claris的代码.. 题 ...

  5. 【BZOJ 2119】 2119: 股市的预测 (后缀数组+分块+RMQ)

    2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 404  Solved: 188 Description 墨墨的妈妈热爱炒股, ...

  6. 【BZOJ】1031: [JSOI2007]字符加密Cipher(后缀数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1031 很容易想到这就是将字符串复制到自己末尾然后后缀数组搞出sa然后按区间输出即可. 然后换了下模板 ...

  7. BZOJ 2754 喵星球上的点名(后缀数组)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2754 题意:给出n个字典串,m个询问串.输出每个询问串出现在多少个字典串中.最后输出每个 ...

  8. bzoj 2754 [SCOI2012]喵星球上的点名 后缀数组+莫队

    先把所有串按顺序放到一起,两个串间加非法字符隔开,求一个后缀数组. 然后对于询问,满足条件的子串在后缀数组上一定是连续一段区间. 这个区间的左右端点可以在读入的过程中二分求. 然后这个问题变成了多组询 ...

  9. BZOJ 1640: [Usaco2007 Nov]Best Cow Line 队列变换

    Description FJ打算带着他可爱的N (1 ≤ N ≤ 2,000)头奶牛去参加"年度最佳老农"的比赛.在比赛中,每个农夫把他的奶牛排成一列,然后准备经过评委检验. 比赛 ...

最新文章

  1. 第八课.Python面向对象(二)
  2. [Node] 重要外部模块
  3. CVE-2012-0158栈溢出漏洞分析
  4. Java:ChronicleMap第1部分,精简版
  5. android中有哪些utils的作用,AndroidUtils
  6. 小程序源码 租房管理系统_如何通过租房小程序开发快速引流
  7. c#中connect函数_C#.NET 各种连接字符串
  8. python在不同系统代码区别_python不同系统中打开方法
  9. 101与金根回顾敏捷个人:(82)《把时间当做朋友》
  10. 不想开滴滴、送外卖的产品经理,听我一声劝……
  11. 微信端打开页面,布局乱了
  12. SpringBoot项目启动报错
  13. bootice添加黑苹果引导_懒人黑苹果安装教程:CLOVER(四叶草)引导
  14. 最简单直接粗暴的Mothur分析OTU教程
  15. iphone铃声android铃声,iphone12如何设置铃声?iphone12更换铃声方式分享[多图]
  16. Matlab帮助文档设置
  17. MySQL旧版本的完整卸载(最全面)
  18. 软件的生命周期及模型
  19. 【TS】1552- 浅谈TS运行时类型检查
  20. 雨中的尾巴(线段树合并+树上差分)

热门文章

  1. python爬虫-Python爬虫入门这一篇就够了
  2. python中文版免费下载-PYTHON自然语言处理(中文最新完整版)pdf下载
  3. python基础教程廖雪峰云-Python 爬虫:把廖雪峰的教程转换成 PDF 电子书
  4. 济南python工资一般多少-济南Python+人工智能
  5. python和java哪个好找工作-你觉得学python还是java好找工作?
  6. shell脚本求和_常用的Shell脚本
  7. java判断字符串是否是空格_检查字符串在Java中是否为空格,空(“”)或null
  8. 超级计算机能算数学题吗,圆周率到底能不能算尽?人类拿超级计算机算了一下,结果不敢相信...
  9. 用c++实现一个插入,删除和随机访问都是O(1)的容器(剑指||30)
  10. 全国计算机考试网页制作,全国计算机信息高新技术考试网页制作(FrontPage平台)网页制作员级考试考试大纲...