算法竞赛入门经典(第二版)
Nicolas Lee
Yesterday you said tomorrow
展开
-
带宽(Bandwidth, UVa 140)
给出一个n(n≤8)个结点的图G和一个结点的排列,定义结点i的带宽b(i)为i和相邻结点在排列中的最远距离,而所有b(i)的最大值就是整个图的带宽。给定图G,求出让带宽最小的结点排列,如图7-7所示。 下面两个排列的带宽分别为6和5。具体来说,图7-8(a)中各个结点的带宽分别为6, 6,1, 4, 1, 1, 6, 6,图7-8(b)中各个结点的带宽分别为5, 3, 1, ...原创 2019-01-11 12:41:59 · 853 阅读 · 0 评论 -
子集生成(无重复集合)------三种方法
给定一个集合,枚举所有可能的子集。集合中没有重复元素。1.增量构造法第一种思路是一次选出一个元素放到集合中,程序如下:用A[i]记录集合S中被选取元素的下标。由于A中记录的元素个数不确定,每次递归调用都要输出当前集合。另外,递归边界也不需要显式确定——如果无法继续添加元素,自然就不会再递归了。下面的代码用到了定序的技巧:规定集合S中所有元素的编号从小到大排列,就不会把集合{1, 2}按...原创 2019-01-09 20:52:49 · 2147 阅读 · 2 评论 -
困难的串(Krypton Factor, UVa 129)回溯
如果一个字符串包含两个相邻的重复子串,则称它是“容易的串”,其他串称为“困难的串”。例如,BB、ABCDACABCAB、ABCDABCD都是容易的串,而D、DC、ABDAB、CBABCBA都是困难的串。输入正整数n和L,输出由前L个字符组成的、字典序第k小的困难的串。例如,当L=3时,前7个困难的串分别为A、AB、ABA、ABAC、ABACA、ABACAB、ABACABA。输入保证答案不超过80...原创 2019-01-10 15:39:44 · 321 阅读 · 0 评论 -
素数环(Prime Ring Problem, UVa 524)递归枚举,回溯
输入正整数n,把整数1, 2, 3,…, n组成一个环,使得相邻两个整数之和均为素数。输出时从整数1开始逆时针排列。同一个环应恰好输出一次。n≤16。样例输入:6样例输出:1 4 3 2 5 61 6 5 2 3 4#include <iostream>#include <cmath>using namespace std;bool isPrime[3...原创 2019-01-10 11:25:20 · 322 阅读 · 0 评论 -
ALGO-129 算法训练 特殊的数字四十
算法训练 特殊的数字四十 时间限制:1.0s 内存限制:256.0MB 特殊的数字四十问题描述 1234是一个非常特殊的四位数,因为它的各位数之和为10,编程求所有这样的四位十进制数。输出格式 按从小到大的顺序输出满足条件的四位十进制数。每个数字占用一行。#include <iostream>using namespace st...原创 2019-01-10 10:06:22 · 253 阅读 · 0 评论 -
生成可重集的排列----C++STL库函数next_permutation使用和自己实现
C++STL库函数next_permutationSTL中的next_permutation 函数和 prev_permutation 两个函数提供了对于一个特定排列P,求出其后一个排列P+1和前一个排列P-1的功能。使用方法:#include<cstdio>#include<algorithm> //包含next_permutationusing nam...原创 2019-01-08 23:26:46 · 538 阅读 · 0 评论 -
除法(Division, UVa 725)
输入正整数n,按从小到大的顺序输出所有形如abcde/fghij = n的表达式,其中a~j恰好为数字0~9的一个排列(可以有前导0),2≤n≤79。样例输入:62样例输出:79546 / 01283 = 6294736 / 01528 = 62【分析】枚举0~9的所有排列?没这个必要。只需要枚举fghij就可以算出abcde,然后判断是否所有数字都不相同即可。不仅程序简单,而且枚举...原创 2019-01-08 20:10:05 · 359 阅读 · 0 评论 -
最大乘积(Maximum Product, UVa 11059)枚举
输入n个元素组成的序列S,你需要找出一个乘积最大的连续子序列。如果这个最大的乘积不是正数,应输出0(表示无解)。1≤n≤18,-10≤Si≤10。样例输入:32 4-352 5 -1 2 -1样例输出:820【分析】连续子序列有两个要素:起点和终点,因此只需枚举起点和终点即可。由于每个元素的绝对值不超过10且不超过18个元素,最大可能的乘积不会超过1018,可以用long lon...原创 2019-01-08 19:59:06 · 256 阅读 · 0 评论 -
分数拆分 Fractions Again UVa 10976
输入正整数k,找到所有的正整数x≥y,使得。样例输入:212样例输出:21/2 = 1/6 + 1/31/2 = 1/4 + 1/481/12 = 1/156 + 1/131/12 = 1/84 + 1/141/12 = 1/60 + 1/151/12 = 1/48 + 1/161/12 = 1/36 + 1/181/12 = 1/30 + 1/201/12 = 1/...原创 2019-01-08 17:34:47 · 187 阅读 · 0 评论 -
Parentheses Balance UVA - 673 栈stack
平衡的括号(Parentheses Balance, UVa 673)输入一个包含“( )”和“[ ]”的括号序列,判断是否合法。具体规则如下:空串合法。如果A和B都合法,则AB合法。如果A合法则(A)和[A]都合法。#include <iostream>#include <stack>#include <map> using namespa...原创 2019-01-08 10:12:38 · 189 阅读 · 0 评论 -
System Dependencies UVA - 506 模拟
软件组件之间可能会有依赖关系,例如,TELNET和FTP都依赖于TCP/IP。你的任务是模拟安装和卸载软件组件的过程。首先是一些DEPEND指令,说明软件之间的依赖关系(保证不存在循环依赖),然后是一些INSTALL、REMOVE和LIST指令,如表6-1所示。表6-1 指令说明指令说明 DEPEND item1 item2 [item3 …] item1依赖组件item2, it...原创 2019-01-08 09:16:23 · 256 阅读 · 0 评论 -
Tree UVA - 548 树的遍历--已知先序中序求权值。
Tree You are to determine the value of the leaf node in a given binary tree that is the terminal node of a path of least value from the root of the binary tree to any leaf. The value of a path is t...原创 2019-01-01 17:47:07 · 306 阅读 · 1 评论 -
战场Paintball UVA - 11853 dfs
战场(Paintball, UVa 11853)有一个1000×1000的正方形战场,战场西南角的坐标为(0,0),西北角的坐标为(0,1000)。战场上有n(0≤n≤1000)个敌人,第i个敌人的坐标为(xi,yi),攻击范围为ri。为了避开敌人的攻击,在任意时刻,你与每个敌人的距离都必须严格大于它的攻击范围。你的任务是从战场的西边(x=0的某个点)进入,东边(x=1000的某个点)离开。如果...原创 2019-01-07 17:54:31 · 274 阅读 · 0 评论 -
Ideal Path UVA - 1599 (2遍bfs)最小中转条件下的最小路径值。
给一个n个点m条边(2≤n≤100000,1≤m≤200000)的无向图,每条边上都涂有一种颜色。求从结点1到结点n的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小。一对结点间可能有多条边,一条边可能连接两个相同结点。输入保证结点1可以达到结点n。颜色为1~10^9的整数。分析:本题只是一个普通的最短路问题,可以用BFS解决。事实上,无须记录父...原创 2019-01-07 12:57:16 · 174 阅读 · 0 评论 -
Self-Assembly UVA - 1572 有向图判断是否有环
UVA - 1572有n(n≤40000)种边上带标号的正方形。每条边上的标号要么为一个大写字母后面跟着一个加号或减号,要么为数字00。当且仅当两条边的字母相同且符号相反时,两条边能拼在一起(00不能和任何边拼在一起,包括另一条标号为00的边)。假设输入的每种正方形都有无穷多种,而且可以旋转和翻转,你的任务是判断能否组成一个无限大的结构。每条边要么悬空(不和任何边相邻),要么和一个...原创 2019-01-05 17:15:51 · 230 阅读 · 0 评论 -
Undraw the Trees UVA - 10562 递归画树
Professor Homer has been reported missing. We suspect that his recent research works might have had something to with this. But we really don’t know much about what he was working on! The detec...原创 2019-01-04 23:07:26 · 410 阅读 · 0 评论 -
Play on Words UVA - 10129 欧拉回路
Play on WordsUVA - 10129 题目类型: 欧拉道路题目:Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because there is no other ...原创 2019-01-03 20:21:21 · 245 阅读 · 0 评论 -
Ordering Tasks UVA - 10305----拓扑排序(dfs)
题目描述约翰有许多工作要做。不幸的是,这个任务并不是独立的,如果其他任务已经执行一个任务的执行是可能的。可以用DFS求出有向无环图(DAG)的拓扑排序。如果排序失败,说明该有向图存在有向环,不是DAG。注意::判断m n是否为0的时候应该用 m||n 来确定两个都为0而不是 m && n !!#include <iostream>#include ...原创 2019-01-02 23:10:31 · 230 阅读 · 0 评论 -
CODE[VS]1288 埃及分数 迭代加深搜索
题目描述:http://codevs.cn/problem/1288/因为深度没有明显的上界,而且加数的选择在理论上也是无限的。故采用迭代加深搜索(iterative deepening):从小到大枚举深度上限dep,每次执行只考虑深度不超过dep的结点。这样,只要解的深度有限,则一定可以在有限时间内枚举到。#include <iostream>#include <c...原创 2019-01-17 18:20:24 · 261 阅读 · 0 评论 -
编辑书稿(Editing a Book, UVa 11212)迭代加深搜索
题目:https://vjudge.net/problem/UVA-11212分析:本题可以用IDA*算法求解。不难发现n≤9时最多只需要8步,因此深度上限为8。IDA*的关键在于启发函数。考虑后继不正确的数字个数h,可以证明每次剪切时h最多减少3,因此当3d+h>3maxd时可以剪枝,其中d为当前深度,maxd为深度限制(3)。如何证明每次剪切时h最多减少3呢?如图7-19所示...原创 2019-01-18 19:38:16 · 314 阅读 · 0 评论 -
天平难题---Mobile Computing 枚举二叉树
给出房间的宽度r和s个挂坠的重量wi。设计一个尽量宽(但宽度不能超过房间宽度r)的天平,挂着所有挂坠。天平由一些长度为1的木棍组成。木棍的每一端要么挂一个挂坠,要么挂另外一个木棍。如图7-9所示,设n和m分别是两端挂的总重量,要让天平平衡,必须满足n*a=m*b。图7-9 天平 ...原创 2019-01-14 15:19:28 · 318 阅读 · 0 评论 -
旋转游戏(The Rotation Game,, UVa1343)迭代加深搜索
题目:https://vjudge.net/problem/UVA-1343结构实现技巧:用数组直接记录相应位置的下标,从而减少了每次赋值给相应数组。#include <iostream>using namespace std;int a[24],maxd;int line[8][7]={ { 0, 2, 6,11,15,20,22}, // A { 1, 3,...原创 2019-01-20 13:35:37 · 248 阅读 · 0 评论 -
八数码问题------三种判重方式 状态空间搜索
编号为1~8的8个正方形滑块被摆成3行3列(有一个格子留空),如图7-14所示。每次可以把与空格相邻的滑块(有公共边才算相邻)移到空格中,而它原来的位置就成为了新的空格。给定初始局面和目标局面(用0表示空格),你的任务是计算出最少的移动步数。如果无法到达目标局面,则输出-1。样例输入:2 6 4 1 3 7 0 5 88 1 5 7 3 6 4 0 2样例输出:31【分析】...原创 2019-01-15 11:33:41 · 4430 阅读 · 0 评论 -
The Morning after Halloween UVA - 1601 万圣节后的早晨, 双向bfs实现
双向广度优先搜索首先需要优化转移代价 https://blog.csdn.net/qq_42835910/article/details/86513282实现:正着搜索一层,反着搜索一层(注意是一层一层的,不是一个一个),然后继续这样交替下去,直到两层中出现相同的状态。 #include <iostream>#include <string>#includ...原创 2019-01-20 21:12:18 · 184 阅读 · 0 评论 -
算法提高 和最大子序列
题目:http://lx.lanqiao.cn/problem.page?gpid=T137分治法:时间复杂度O(nlogn)#include <iostream>using namespace std; int a[100001];int maxSum(int x,int y){ if(y-x==1) return a[x]; int m=x+(y-x)/2; ...原创 2019-01-25 15:39:04 · 258 阅读 · 0 评论 -
倒水问题(Fill, UVa 10603)状态空间搜索
你的任务是解决一般性的问题:设3个杯子的容量分别为a, b, c,最初只有第3个杯子装满了c升水,其他两个杯子为空。最少需要倒多少升水才能让某一个杯子中的水有d升呢?如果无法做到恰好d升,就让某一个杯子里的水是d'升,其中d'<d并且尽量接近d。(1≤a,b,c,d≤200)。要求输出最少的倒水量和目标水量(d或者d')。【分析】:由于无论如何倒,杯子中的水量都是整数(按照倒水次数...原创 2019-01-15 16:59:10 · 614 阅读 · 0 评论 -
快速幂计算(Power Calculus, UVa1374)迭代加深搜索
题目:https://vjudge.net/problem/UVA-1374 【分析】使用迭代加深搜索,d表示当前深度,maxd表示深度上限,则如果当前序列最大的数乘以2maxd-d之后仍小于n,则剪枝。另外,为了尽快接近目标,不应该“任选”两个数,而应该先选较大的数,并且先试加法再试减法(6)。这样做可以在最后一次迭代(即找到解的那次迭代)中比较快地找到解,从而终止整个搜索过程,而不需要...原创 2019-01-21 14:05:24 · 331 阅读 · 0 评论 -
Stacks of Flapjacks UVA - 120 煎饼 构造法
题目:https://vjudge.net/problem/UVA-120【分析】这道题目要求排序,但是基本操作却是“颠倒一个连续子序列”。不过没有关系,我们还是可以按照选择排序的思想,以从大到小的顺序依次把每个数排到正确的位置。方法是先翻到最上面,然后翻到正确的位置。由于是按照从大到小的顺序处理,当处理第i大的煎饼时,是不会影响到第1, 2, 3,…, i-1大的煎饼的(它们已经正确地翻到...原创 2019-01-25 20:43:26 · 188 阅读 · 0 评论 -
基础练习 Huffuman树
题目链接 蓝桥杯---基础练习 题解问题描述 Huffman树在编码中有着广泛的应用。在这里,我们只关心Huffman树的构造过程。 给出一列数{pi}={p0,p1, …,pn-1},用这列数构造Huffman树的过程如下: 1. 找到{pi}中最小的两个数,设为pa和pb,将pa和pb从{pi}中删除掉,然后将它们的和加入到{pi}中。这个过程的费用记为p...原创 2019-01-26 16:08:03 · 233 阅读 · 0 评论 -
Building for UN UVA - 1605 联合国大楼 构造法
题目:https://vjudge.net/problem/UVA-1605 思路:一共只有两层,每层都是n*n的,第一层第i行全是国家i,第二层第j列全是国家j。这样每个国家肯定相邻#include <iostream>using namespace std;char country(int i){ return i>=26 ? 'a'+i-26 : 'A'+...原创 2019-01-26 17:32:18 · 277 阅读 · 0 评论 -
4 Values whose Sum is 0 UVA - 1152 中途相遇法
题目:https://vjudge.net/problem/UVA-1152【分析】最容易想到的算法就是写一个四重循环枚举a, b, c, d,看看加起来是否等于0,时间复杂度为O(n4),超时。一个稍好的方法是枚举a, b, c,则只需要在集合D里找找是否有元素-a-bc,如果存在,则方案加1。如果排序后使用二分查找,时间复杂度为O(n3logn)。把刚才的方法加以推广,就可以得到一个...原创 2019-01-26 19:52:47 · 465 阅读 · 0 评论 -
P1216 [IOI1994]数字三角形 Number Triangles 计算状态转移的方法
题目:题目链接计算状态转移的方法:方法一:递推计算。时间复杂度显然是O(n*n)。递推的关键是边界和计算顺序。在多数情况下,递推法的时间复杂度是:状态总数×每个状态的决策个数×决策时间。如果不同状态的决策个数不同,需具体问题具体分析。程序如下(需注意边界处理):#include <iostream>using namespace std;const int N=1...原创 2019-01-31 20:09:03 · 283 阅读 · 0 评论 -
Fabled Rooks UVA - 11134 传说中的车 问题分解
题目:https://vjudge.net/problem/UVA-11134 【分析】两个车相互攻击的条件是处于同一行或者同一列,因此不相互攻击的条件就是不在同一行,也不在同一列。可以看出:行和列是无关的,因此可以把原题分解成两个一维问题。在区间[1~n]内选择n个不同的整数,使得第i个整数在闭区间[n1i, n2i]内。思路:将[min,max]用max大小进行排序,排好序后在1~n...原创 2019-01-27 19:40:22 · 219 阅读 · 0 评论 -
万圣节后的早晨(The Morning after Halloween, UVa1601)优化转移代价
题目:https://vjudge.net/problem/UVA-1601优化转移代价:因为要走的节点不止一个,容易超时,故需优化转移代价,将迷宫转化为图(即邻接矩阵转化为邻接表),减少判断。之前用的结构体实现储存状态,现在改成了编码、解码来储存,觉得能够节省空间挺好的,但是之后发现运行时间变长了,可能是每次编码、解码都要调用运算的原因吧。代码如下#include <iostre...原创 2019-01-16 19:47:57 · 561 阅读 · 0 评论 -
洛谷 CF4D Mysterious Present 嵌套矩形 DAG
题目链接【分析】方法一:先排序(按照宽度 or 长度),再dp。 状态转移方程 #include <iostream>#include <algorithm>#include <cstring>using namespace std;const int N = 5005; struct Rectangle{ int w,h,...原创 2019-02-01 17:16:46 · 353 阅读 · 0 评论 -
Square Destroyer UVA - 1603 破坏正方形
题目链接【分析】不难想到用迭代加深搜索作为主算法框架。搜索对象有两种:(1)每次考虑一个没有被破坏的正方形,在边界上找一根火柴拿掉;(2)每次找一个至少能破坏一个正方形的火柴,然后拿掉。两种方法各有不同的优化方法:搜索对象是正方形。应先考虑小正方形,再考虑大正方形,因为破坏完小正方形之后,很多大正方形已经被破坏了,但是反过来却不一定。还可以加入最优性剪枝,即把每个正方形看成一个顶点,有公共火...原创 2019-01-22 21:03:49 · 324 阅读 · 0 评论 -
算法训练 星际交流 排列生成问题
题目链接 蓝桥杯 算法训练---------题解问题描述 人类终于登上了火星的土地并且见到了神秘的火星人。人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法。这种交流方法是这样 的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小的数字加到这个大数上面,...原创 2019-01-22 22:10:26 · 403 阅读 · 0 评论 -
硬币问题 DAG模型
问题描述:有n种硬币,面值分别为V1, V2, …, Vn,每种都有无限多。给定非负整数S,可以选用多少个硬币,使得面值之和恰好为S?输出硬币数目的最小值和最大值。1≤n≤100,0≤S≤10000,1≤Vi≤S。【分析】本题的本质是DAG上的路径问题。将每种面值看作一个点,表示“还需要凑足的面值”,则初始状态为S,目标状态为0。若当前在状态i,每使用一个硬币j,状态便转移到i-Vj。而...原创 2019-02-02 20:37:54 · 551 阅读 · 0 评论 -
Amphiphilic Carbon Molecules UVA - 1606 两亲性分子 扫描法
题目:https://vjudge.net/problem/UVA-1606 扫描法。扫描法类似于一种带有顺序的枚举法。例如,从左到右考虑数组的各个元素,也可以说从左到右“扫描”。它和普通枚举法的重要区别是:扫描法往往在枚举时维护一些重要的量,从而简化计算。【分析】不妨假设隔板一定经过至少两个点(否则可以移动隔板使其经过两个点,并且总数不会变小),则最简单的想法是:枚举两个点,然后输出两...原创 2019-01-28 20:22:59 · 215 阅读 · 0 评论 -
Cutting Sticks UVA - 10003 切木棍 线性dp
题目链接有一根长度为L(L<1000)的棍子,还有n(n<50)个切割点的位置(按照从小到大排列)。你的任务是在这些切割点的位置处把棍子切成n+1部分,使得总切割费用最小。每次切割的费用等于被切割的木棍长度。例如,L=10,切割点为2, 4, 7。如果按照2, 4, 7的顺序,费用为10+8+6=24,如果按照4, 2, 7的顺序,费用为10+4+6=20。【分析】设d(i,j)为切割小木...原创 2019-02-14 16:59:59 · 392 阅读 · 0 评论