字典序

HDU 1716 排列2

最后都变了- 提交于 2020-04-04 01:46:13
排列2 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3107 Accepted Submission(s): 1220 Problem Description Ray又对数字的列产生了兴趣: 现有四张卡片,用这四张卡片能排列出很多不同的4位数,要求按从小到大的顺序输出这些4位数。 Input 每组数据占一行,代表四张卡片上的数字(0<=数字<=9),如果四张卡片都是0,则输入结束。 Output 对每组卡片按从小到大的顺序输出所有能由这四张卡片组成的4位数,千位数字相同的在同一行,同一行中每个四位数间用空格分隔。 每组输出数据间空一行,最后一组数据后面没有空行。 Sample Input 1 2 3 4 1 1 2 3 0 1 2 3 0 0 0 0 Sample Output 1234 1243 1324 1342 1423 1432 2134 2143 2314 2341 2413 2431 3124 3142 3214 3241 3412 3421 4123 4132 4213 4231 4312 4321 1123 1132 1213 1231 1312 1321 2113 2131 2311 3112 3121

第三次作业结对编程

那年仲夏 提交于 2020-04-02 18:29:08
第三次作业结对编程 1.地址 GIT地址 https://github.com/qq319064057/WordCount GIT用户名 qq319064057 结对伙伴地址 https://www.cnblogs.com/tyx666/ 博客地址 https://www.cnblogs.com/319064057-lx/ 作业链接 https://www.cnblogs.com/319064057-lx/p/10660199.html 2.PSP表 PSP Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 20 20 Estimate 估计这个任务需要多少时间 20 20 Development 开发 600 710 Analysis 需求分析 (包括学习新技术) 50 40 Design Spec 生成设计文档 30 20 Design Review 设计复审 (和同事审核设计文档) 20 30 Coding Standard 代码规范 (为目前的开发制定合适的规范) 20 15 Design 具体设计 30 45 Coding 具体编码 360 300 Code Review 代码复审 60 50 Test 测试(自我测试,修改代码,提交修改) 30 30 Reporting 报告 90 70

字典序算法

和自甴很熟 提交于 2020-03-22 18:01:53
全排列的生成算法 对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。 字典序法 按照字典序求下一个排列的算法 /* 例 字符集 {1,2,3}, 较小的数字较先 , 这样按字典序生成的全排列是 :123,132,213,231,312,321 。 注意 一个全排列可看做一个字符串,字符串可有前缀、后缀。 */ 生成给定全排列的下一个排列 所谓一个 全排列 的下一个排列就是这一个排列与下一个排列之间没有其他的排列。这就要求这一个排列与下一个排列有尽可能长的共同前缀,也即变化限制在尽可能短的后缀上。 /* 例 839647521 是 1 — 9 的排列。 1 — 9 的排列最前面的是 123456789 ,最后面的是 987654321 ,从右向左扫描若都是增的,就到了 987654321 ,也就没有下一个了。否则找出第一次出现下降的位置。 算法: 由 P 1 P 2 …P n 生成的下一个排列的算法如下: 1. 求 i=max{j| P j-1 <P j } 2. 求 l =max{k| P i-1 <P k } 3. 交换P i-1 与P l 得到 P 1 P 2 … P i-1 ( P i.... P n ) , 将红色部分顺序逆转,得到结果. 例 求 8396 4 7521 的下一个排列 1. 确定i,从左到右两两比较找出后一个数比前一个大的组合

贪心法解决最小字典序问题

独自空忆成欢 提交于 2020-03-12 16:26:50
问题描述: 给定一个长度为n的字符串S,构造一个字符串T,长度也为n;起初,T是一个空字符串,随后反复进行以下操作: 1、从S的头部删除一个字符,加到T的尾部。 2、从S的尾部删除一个字符;加到T的尾部。 目标是:最后生成的字符串T的字典序尽可能小。 解题思路: 每次选取的时候将头尾两个字符对比,将字典序小的删除并添加到T中。我们可以将S给逆序,保存为另一个字符串。然后将逆序的S和正序的S首字符的进行对比(其实首字符的对比就是字符串的对比,因为首字符相同会进行第二个字符的对比,这样可以避免我们将一个字符串的头尾对比带来头尾指针移动的麻烦),选出字典序小的删除并添加到T中。 代码如下: import java . util . * ; public class 最小字典序 { public static void main ( String [ ] args ) { Scanner scanner = new Scanner ( System . in ) ; String s = scanner . nextLine ( ) ; int n = s . length ( ) ; System . out . println ( f ( s , n ) ) ; } private static String f ( String s , int n ) { String s1 =

NOIP 双栈排序(贪心算法)

跟風遠走 提交于 2020-02-26 22:38:58
题目描述 Tom最近在研究一个有趣的排序问题。如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序。 操作a 如果输入序列不为空,将第一个元素压入栈S1 操作b 如果栈S1不为空,将S1栈顶元素弹出至输出序列 操作c 如果输入序列不为空,将第一个元素压入栈S2 操作d 如果栈S2不为空,将S2栈顶元素弹出至输出序列 如果一个1~n的排列P可以通过一系列操作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”。例如(1,3,2,4)就是一个“可双栈排序序列”,而(2,3,4,1)不是。下图描述了一个将(1,3,2,4)排序的操作序列:<a,c,c,b,a,d,d,b> 当然,这样的操作序列有可能有几个,对于上例(1,3,2,4),<a,c,c,b,a,d,d,b>是另外一个可行的操作序列。Tom希望知道其中字典序最小的操作序列是什么。 【输入】 输入文件twostack.in的第一行是一个整数n。 第二行有n个用空格隔开的正整数,构成一个1~n的排列。 【输出】 输出文件twostack.out共一行,如果输入的排列不是“可双栈排序排列”,输出数字0;否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。 【输入输出样例1】 输入: 4 1 3 2 4 输出: a b a a b b a b 思路 能弹出,则弹出

Codeforces Round #618 (Div. 2)

时光总嘲笑我的痴心妄想 提交于 2020-02-11 21:23:53
A. Non-zero 题意:给一串数字,每次可以对一个数字+1,问最少多少次操作之后所有数的和和乘积均不为0。 思路:乘积更容易处理,只要所有数字非0即可,于是对所有0(可以没有)操作一次,然后如果当前数字和不为0,则结束,为0,则对一个非负数操作一次(必然存在)。 代码中特判了全为-1的情况,事实上毫无意义,因为全为-1的情况在前面就会背判断掉。 1 #include<bits/stdc++.h> 2 #define LL long long 3 #define dl double 4 void rd(int &x){ 5 x=0;int f=1;char ch=getchar(); 6 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 7 while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f; 8 } 9 void lrd(LL &x){ 10 x=0;int f=1;char ch=getchar(); 11 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f; 13 } 14

【哈希】Gym - 102448 - C - Call from Mendes

强颜欢笑 提交于 2020-02-05 00:04:33
题目链接 http://codeforces.com/gym/102448/problem/C 题意 三种操作,一共有 Q Q Q 个: 1    X 1\;X 1 X :在字典里插入字符串 X X X 2    X 2\;X 2 X :在字典里删除字符串 X X X 3    X 3\; X 3 X :输出字典中最短的且前缀是 X X X 的下标。如果有多个字符串,输出字典序最小的。 字符串的下标是指该串被插入时的时间。 输入中所有的字符串长度和不超过 1 0 6 10^6 1 0 6 题解 第一眼感觉是可持久化AC自动机?不会啊。然后就看到了这个条件:所有的字符串长度和不超过 1 0 6 10^6 1 0 6 ,决定乱搞。 对每个长度开一个 m a p < h a s h , s e t > [ i ] map<hash, set>[i] m a p < h a s h , s e t > [ i ] ,表示存在一个 s e t set s e t 的字符串满足长度为 i i i 的前缀哈希值是 h a s h hash h a s h 。 s e t set s e t 里记录一下字符串的信息,比如长度啊,字典序啊,下标啊。这个字典序我的求法就比较夸张,直接全部读进来,离散排个序。 然后三种操作只要对应的把 m a p map m a p 和 s e t set s e t

省选模拟赛第一场 T1反攻密令(后缀数组统计本质不同的子串数量+二分答案)

别等时光非礼了梦想. 提交于 2020-01-30 10:29:31
题解 字符串果然还是我的弱项。。。还得继续刷后缀数组和AC自动机 在讨论这道题之前,先来想一下后缀数组有什么用 1、后缀排序 2、O(nlogn)预处理ST表,O(1)求LCP 好像没有什么了吧。。。 其实它的用处还有很多很多: https://blog.csdn.net/c20181220_xiang_m_y/article/details/104017226 这里用到了它的一个用处:把所有本质不同的子串进行排序 怎么做? 把排序好的后缀数组拿出来,从小到大枚举排名 i ,以sa[i]作为左端点,j从sa[i]+height[i]枚举到n,以 j 作为右端点 然后发现这些子串都是本质不同且字典序递增的(其实想想就知道为什么了) 于是我们就可以来对n-(sa[i]+height[i])+1做一个前缀和,就可以用lower_bound来查出一个排名对应的子串啦 这道题要求的就是所有划分方案中,对于一个划分方案,求出它划分后的所有串的最大子串的最大串,然后求所有方案的答案的最小串。最小化最大值,可以联想到二分 我们发现对于一个串,如果要成为答案,那么所有字典序大于它的串必须被划分到多个段 当我们二分了一个串,可以考虑倒序贪心,当遇到一个整串的字典序大于二分的答案,我们就把它与它的第一个字符划分成两段 (为什么是倒序,因为固定了一个右端点,左端点l到右段点r中的所有前缀的最大值就是l

Codeforces Round #615 (Div. 3)

六月ゝ 毕业季﹏ 提交于 2020-01-23 03:53:19
暂时没有F题的题解。太菜了。 A - Collecting Coins 题意:有三个人,分别有a,b,c枚硬币,你有n枚硬币,要求把n枚硬币全部给这三个人并且使得他们的硬币数变为相等。问是否可行。 题解:先验证硬币总数a+b+c+n是否能被3整除,然后验证要补的硬币的数量少于n。 void test_case() { int a[5], n; scanf("%d%d%d%d", &a[1], &a[2], &a[3], &n); sort(a + 1, a + 1 + 3); int sum = a[3] - a[1] + a[3] - a[2]; if(sum > n || (sum - n) % 3 != 0) puts("NO"); else puts("YES"); } B - Collecting Packages 题意:有个机器人,只能向上走或者向右走,要从(0,0)经过所有的点(xi,yi),求是否可行,若可行则输出字典序最小的方案。 题解:字典序最小就是说先往右走再往上走。直接把所有点按x排序,要求每个点与(0,0)包围的矩形包含此前的所有点,只需要比前面的点都高就行了。由数学归纳法可知只需要比前一个点高就行了。 int n; pii p[1005]; void test_case() { scanf("%d", &n); for(int i = 1; i <= n

后缀数组

。_饼干妹妹 提交于 2020-01-19 02:50:17
后缀数组个人感觉的确有点复杂,看了挺久的,听说后缀数组是一种神仙操作,忘记在哪听到这个就学了一下 学习博客:https://www.cnblogs.com/victorique/p/8480093.html 什么是后缀数组 我们先看几条定义: 子串 在字符串s中,取任意i<=j,那么在s中截取从i到j的这一段就叫做s的一个子串 后缀 后缀就是从字符串的某个位置i到字符串末尾的子串,我们定义 以s的第i个字符为第一个元素的后缀为suff(i) 后缀数组 把s的每个后缀按照字典序排序, 后缀数组sa[i]就表示 排名为i的后缀 的起始位置的下标 而它的映射数组rk[i]就表示 起始位置的下标为i的后缀 的排名 简单来说,sa表示排名为i的是啥,rk表示第i个的排名是啥 一定要记牢这些数组的意思,后面看代码的时候如果记不牢的话就绝对看不懂 后缀数组的思想 先说最暴力的情况,快排(n log n)每个后缀,但是这是字符串,所以比较任意两个后缀的复杂度其实是O(n),这样一来就是接近O(n^2 log n)的复杂度,数据大了肯定是不行的,所以我们这里有两个优化。 ps:本文中的^表示平方而不是异或 倍增 首先读入字符串之后我们现根据单个字符排序,当然也可以理解为先按照每个后缀的第一个字符排序。对于每个字符,我们按照字典序给一个排名(当然可以并列),这里称作关键字。