算法竞赛入门经典(训练指南)
文章平均质量分 79
XDU_Skyline
Everything is over, everything is just beginning.
展开
-
例题1.16 长城守卫 UVa1335
1.题目描述:点击打开链接2.解题思路:本题是一道思维题。这种题一般需要先自己在演草纸上多尝试几种情况,并总结出一般的规律解决。尝试后,可以发现,如果n为偶数时,那么结果就是max{r[i]+r[i+1]}(规定r[n+1]=r[1])。如果n为奇数时,上述方法不再奏效。这个时候需要利用二分查找,假设共有p种礼物,设第一个人的礼物是1~r[1]。不难发现最优解的策略一定是这样的:如果i为偶数,原创 2015-03-14 21:53:03 · 876 阅读 · 0 评论 -
例题1.19 计算器谜题 UVa11549
1.题目描述:点击打开链接2.解题思路:本题是一道普通的模拟题,根据题意易知计算器显示的数将会出现循环,因为显示的n位数一共就有限种情况,而平方的次数是无限多的。所以不妨一个个的模拟,每次都看新得到的数是否以前出现过,如果出现过就跳出循环。但如何判断是否出现过呢?第一种方法是利用STL中的set,同时写一个Next函数求出下一个k值。下面一共给出三个不同的代码,来分别体会一下效率上的巨大差异。原创 2015-03-15 12:06:51 · 649 阅读 · 0 评论 -
例题1.22 最大子矩阵 UVa1330
1.题目描述:点击打开链接2.解题思路:本题利用扫描法解决:从上向下扫描每一行,如果我们把每个格子向上延伸的连续空格看做一条悬线,并用up(i,j),left(i,j),right(i,j)表示格子(i,j)的悬线长度以及该悬线向左,向右能够运动的“运动极限”,即最远能够走到哪一列。这样,每个格子(i,j)对应着一个以第i行为下边界,高度为up(i,j),宽度为right(i,j)-left(原创 2015-03-15 19:45:31 · 597 阅读 · 0 评论 -
例题1.21 子序列 UVa1121
1.题目描述:点击打开链接2.解题思路:本题是典型的二分搜索题,二分答案后验证是否满足和大于等于S即可。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#include#include#include#include#include#include#include#include#incl原创 2015-03-15 17:13:45 · 723 阅读 · 0 评论 -
例题1.23 遥远的银河 UVa1382
1.题目描述:点击打开链接2.解题思路:本题要求找一个矩形,使得边上的点数最大。看上去比较棘手,如果只是单纯地枚举每行,每列,再加上要统计点数,时间复杂度会高达O(N^5),无法承受。因此,需要转变思路。做了这么多题,会发现,这种带有统计目的的题目常常采用的策略就是先扫描,计算出一些必要的信息,例如前缀和等。将来处理时就能用O(1)时间得到想要的结果,便于寻找某种最优值。本题照样如此。对于原创 2015-03-15 22:06:40 · 820 阅读 · 0 评论 -
例题3.1 猜猜数据结构 UVa11995
1.题目描述:点击打开链接2.解题思路:本题要求根据输入的数据和输出的数据来猜测一种可能的数据结构,备选答案有“栈,队列,优先队列”,结果也可能都不是或者不确定。STL中已经有这三种数据结构了,因此直接模拟题意,输出时判断是否对应即可。注意:弹出时要判断一下是否已经为空。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#i原创 2015-03-16 17:11:20 · 885 阅读 · 0 评论 -
例题3.2 一道简单题 UVa11991
1.题目描述:点击打开链接2.解题思路:本题要求在一串数中找第k个v的下标,属于数据结构题。我们自然会想:如果能够直接读出data[v][k]该多好。这时,就可以联想到STL中的map。把v当做“键”,由于要找的是第k个,说明“值”是一个不定长的数组,那么自然要使用vector,这样就可以用map >a来实现类似于data[v][k]的数据结构了。3.代码:#define _CRT_S原创 2015-03-16 22:36:48 · 585 阅读 · 0 评论 -
例题2.26 解方程 UVa10341
1.题目描述:点击打开链接2.解题思路:本题要求解一个超越方程,通过观察发现,方程的前五项在区间[0,1]上单调递减,因此如果端点F(0)≤0或F(1)≥0,则无解。否则,一定有解。此时可以利用二分搜素来求出解。由于实数区间可以无限二分,因此通常是当区间长度小于特定值eps时终止,例如eps=1e-5;也可以当迭代次数超过一定值时终止,例如100次。3.代码:#define _CRT_原创 2015-03-16 22:56:57 · 585 阅读 · 0 评论 -
例题2.27 误差曲线 UVa1476
1.题目描述:点击打开链接2.解题思路:本题要求求出若干条抛物线在给定的区间[0,1000]内的最小值。根据F(x)的定义可以发现,它的形状仍然是下凸的,因此可以利用三分搜索(ternary search)解决。三分搜索的思想是:如果F(x)是一个下凸函数,取区间[L,R]的两个三分点m1,m2,比较F(m1)和F(m2)的大小,如果F(m1)3.代码:#define _CRT_SEC原创 2015-03-16 23:29:26 · 703 阅读 · 0 评论 -
例题3.4 K个最小和 UVa11997
1.题目描述:点击打开链接2.解题思路:本题是多路归并问题,即有n个有序表,需要将这n个有序表合成一个有序表。多路归并问题的一般解法是利用优先队列解决,优先队列q中初始存入每个表的第一个元素,然后每次出一个元素,就把它放入新表,并将它所在的表的下一个元素值加入队列。本题的关键点在于如何将这n组元素转化为上述多路归并问题。我们先考虑一个简化版本的问题,给出两个长度为n的有序表A和B,分别在A原创 2015-03-17 18:56:06 · 754 阅读 · 0 评论 -
例题3.5 易爆物 UVa1160
1.题目描述:点击打开链接2.解题思路:本题利用并查集解决。我们把每个元素看做一个顶点,则一个简单化合物就是一条边。当整个图存在环的时候,组成环的边对应的化合物是危险的,反之则是安全的。这样,可以通过并查集来维护图的连通分量集合,每次得到一个简单化合物,检查x和y是否在同一个集合中,如果是,则拒绝,反之则接受。3.代码:#define _CRT_SECURE_NO_WARNINGS原创 2015-03-17 20:21:03 · 524 阅读 · 0 评论 -
例题3.8 频繁出现的数值 UVa11235
1.题目描述:点击打开链接2.解题思路:本题属于RMQ问题。注意到整个数组是非降序的,所有相等的元素都会聚在一起,这样就可以把整个数组进行游程编码(Run Lengh Encodeing RLE)。比如-1,1,2,2,2,4就可以表示为(-1,1),(1,2),(2,3),(4,1)。其中(a,b)表示有b个连续的a。本题中,用Left[pos],Right[pos]分别表示位置pos所在段原创 2015-03-20 15:40:29 · 566 阅读 · 0 评论 -
例题3.3 阿格斯 UVa1203
1.题目描述:点击打开链接2.解题思路:本题利用优先队列解决。根据题意,优先出列的是时间靠前的时间,如果当有多个事件同时发生,那么再考虑Qnum小的事件优先出列。本题有一个重要的技巧,就是每次出列后,更新一下该元素下次出列的时间,然后再次放回队列,使得优先队列中一直都是n个元素。由于只模拟前k个时间,而STL的priority_queue的出列时间复杂度是O(logN),因此本题的总时间复杂度原创 2015-03-17 18:33:09 · 741 阅读 · 0 评论 -
例题2.28 桥上的绳索 UVa1356
1.题目描述:点击打开链接2.解题思路:本题算是一道微积分题目,首先根据题目条件列写方程:间隔数n=ceil(B/D),每个间隔宽度D1=B/n,每段绳索长度L1=L/n。接下来就是根据D1,L1来计算底部离地面的高度y了。不过我们会发现,这个方程很难找到求解公式,因此应该转移思路,试图利用数值问题中的二分法逐渐逼近这个高度值。设函数P(w,h)计算出来抛物线的长度,其中w表示抛物线开口的宽度原创 2015-03-17 13:16:13 · 770 阅读 · 0 评论 -
例题1.18 开放式学分制 UVa11078
1.题目描述:点击打开链接2.解题思路:本题一看n的范围高达100000,肯定只能用O(N)的复杂度解决。本题类似于最大连续和问题,事先计算区间[0,i)的最大值,存放到_max数组中,然后扫描整个数组,不断用max(ans,_max[i]-a[i])更新最大差值即可。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#in原创 2015-03-12 22:09:10 · 668 阅读 · 0 评论 -
例题1.1 勇者斗恶龙 UVa11292
1.题目描述:点击打开链接2.解题思路:本题用贪心法解决,事先对恶龙的直径,能力值从小到大排序,由于要试图杀掉所有的恶龙,因此枚举每只恶龙,用cur来表示当前骑士的下标,如果他恰好能杀掉恶龙,就用他,否则尝试下一个。如果cur与m相等时退出循环,若此时恶龙仍未被杀光,则无解,反之输出ans。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#原创 2015-03-09 23:19:19 · 918 阅读 · 0 评论 -
例题3.9 动态最大连续和 UVa1400
1.题目描述:点击打开链接2.解题思路:本题利用线段树解决。事先构造一棵线段树,在每个线段树的结点中维护三个成员变量:max_sub,max_prefix,max_suffix。设此时线段树结点为x,左右端点分别为l,rmax_sub:区间连续最大和max_prefix:区间前缀最大和max_suffix:区间后缀最大和为了同时知道上述三个最大和的左右端点,令它们都是一个结构体se原创 2015-03-21 11:39:57 · 599 阅读 · 0 评论 -
例题1.6 立方体成像 UVa1030
1.题目描述:点击打开链接2.解题思路:本题只给了六个视图,要求找最大的立方块数,看上去貌似很棘手的一个问题。我们可以尝试用排除法,如果删到不能删除时,那么剩下的立方块自然就是最多的。由于视图中为‘.'的地方一定可以看穿,因此可以把这些能看穿的位置的立方体先去掉。接下来,题目还已知了一个小立方块的六个面都是同色的,如果发现某个立方体存在两个面不同色,那么说明该位置的立方块肯定不存在。把该位置的原创 2015-03-11 18:40:34 · 1234 阅读 · 1 评论 -
例题1.4 墓地雕塑 UVa1388
1.题目描述:点击打开链接2.解题思路:本题的解法颇为巧妙,应用了逆向思维。假设最后这n+m个雕塑已经摆放好,不妨将它们两两之间的距离看做单位1,那么计算之前的位置坐标。这里都以其中一个为圆周上的坐标原点。那么原来的雕塑中第i个的距离是pos=i/n*(n+m),因此看它离哪个整数比较接近,就移动到那个整数。而选择距离最近的那个整数只用把i/n*(n+m)四舍五入即可,即floor(pos+0原创 2015-03-10 18:47:39 · 999 阅读 · 0 评论 -
例题1.3 分金币 UVa11300
1.题目描述:点击打开链接2.解题思路:本题要求若干个人分金币时交换的最少金币数。由于最后每个人获得的金币数量一样,即平均值M,那么我们可以设出来第i个人传递给第i+1个人的金币数量是Xi(把队列当做循环的),那么每个人都可以看做一个结点,根据结点可以列写相应的转移方程:Ai+X(i-1)-X(i)=M。整理后发现,每个Xi都等于X1-|Ai-M|,令Ci=|Ai-M|,所以本题就是求sum{原创 2015-03-10 18:13:55 · 768 阅读 · 0 评论 -
例题1.5 蚂蚁 UVa10881
1.题目描述:点击打开链接2.解题思路:本题是一道很经典的题目,锻炼思维的。蚂蚁在杆子上相互碰撞,反弹,从远处看去,好像直接穿过,除此之外,每只蚂蚁的相对位置是不变的。本题就是从这两处突破口编程解决的。因此,我们可以最初把他们看做直接穿过,到最后再确定他们”谁是谁“即可。由于最初输入时是乱序(没有按照位置由小到大输入),因此应该先记录输入的序号,按照位置排序后用一个order数组标记第i个输入原创 2015-03-10 21:11:14 · 622 阅读 · 0 评论 -
例题1.2 突击战 UVa11729
1.题目描述:点击打开链接2.解题思路:本题利用贪心法解决。由于让总时间最短,因此可以先安排执行时间最长的任务,因为安排任务的总时间是无法改变的,总时间取决于执行任务的最长时间,因此应该先安排执行时间最长的任务。具体证明自己画图即可得证。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#include#原创 2015-03-10 16:04:05 · 682 阅读 · 0 评论 -
例题1.7 偶数矩阵 UVa11464
1.题目描述:点击打开链接2.解题思路:本题利用暴力搜索解决。不过要采用适当的枚举策略才能防止TLE。由于题目中n的最大值是15,通过观察可以发现,我们可以根据第一行的情况即可推算出下面各行的解,也就是说整个矩阵的解完全取决于第一行的情况。又因为每个元素非0即1,所以可以想到枚举集合。这样,每次枚举第一行的一个状态,然后用check函数去计算改变的个数,无解时输出INF。这样整道题的时间复杂度原创 2015-03-11 22:16:16 · 801 阅读 · 0 评论 -
例题1.17 年龄排序 UVa11462
1.题目描述:点击打开链接2.解题思路:一道纸老虎题。。。难以置信,很直白的排序题,第一感觉直接用sort,看这题数据能否hack我,看来是我想多了。。。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#include#include#include#include#include#includ原创 2015-03-12 21:42:10 · 578 阅读 · 0 评论 -
例题1.10 正整数序列 UVa11384
1.题目描述:点击打开链接·2.解题思路:本题属于找规律题。通过多次尝试,可以发现,我们可以每次让所有大于n/2都减去n/2,这样得到的结果等价于序列1~n/2,令f(n)表示序列1~n的操作次数,那么f(n)=f(n/2)+1。边界是f(1)=1。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#inc原创 2015-03-12 18:11:44 · 724 阅读 · 0 评论 -
例题1.12 组装电脑 UVa12124
1.题目描述:点击打开链接2.解题思路:本题要求最小值最大化,一般方法是利用二分查找解决,即每次都枚举一个品质因子x,删除所有品质因子小于x的配件,如果可以组装出一台不超过b元的电脑,那么ans≥b,否则ans本题需要防止TLE,在判断的时候进行适当的优化,比如设置一个cheapest变量表示最便宜的价格,初始为b+1,若枚举完该类型的所有配件后还是b+1,说明无法组装;另外可以在每次累加原创 2015-03-13 16:33:27 · 719 阅读 · 0 评论 -
例题1.14 填充正方形 UVa11520
1.题目描述:点击打开链接2.解题思路:本题要求字典序最小,由于n的范围比较小,直接尝试按照字典序填写每个格子即可。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#include#include#include#include#include#include#include#include原创 2015-03-13 21:26:08 · 756 阅读 · 0 评论 -
例题1.15 网络 UVALive 3902
1.题目描述:点击打开链接2.解题思路:本题要求放置尽可能少的服务器,使得所有的客户端到最近的服务器的距离都不超过k。由于已经放置了一个服务器,不妨把它当做根结点,先把无根树转化为有根树,然后我们考虑最深的叶子,那么不难证明,该叶子结点的最优服务器的放置位置是它的k级祖先。这样本题的算法便不难想出:从最深的叶子开始枚举,并在它的k级祖先处放置一个服务器,同时标记该服务器能覆盖到的所有结点,这样原创 2015-03-13 23:05:09 · 669 阅读 · 0 评论 -
例题1.13 派 UVa12097
1.题目描述:点击打开链接2.解题思路:本题还是利用二分搜索解决,设函数ok(x)表示是否可以让每个人分到一块面积为x的派,然后进行二分搜索即可。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#include#include#include#include#include#include#i原创 2015-03-13 19:29:35 · 574 阅读 · 0 评论 -
例题3.6 合作网络 UVa1329
1.题目描述:点击打开链接2.解题思路:本题利用并查集解决。因为从题目的要求可知,只涉及距离查询到根结点的距离,因此除了根结点外,其他结点的位置可以任意改变,只是要维护到父结点的距离。当进行路径压缩时,更新这个距离值即可。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#include#include原创 2015-03-17 20:53:56 · 546 阅读 · 0 评论 -
例题3.7 乒乓比赛 UVa1428
1.题目描述:点击打开链接2.解题思路:根据题意,考虑第i个人当裁判的情况,假设第1个人到第i-1个人中,有num1个人的经验值小于A[i],那么就有i-1-num1个人的经验值大于A[i];同理,假设第i+1个人到第n个人之见有num2个人的经验值小于A[i],那么就有n-i-num2个人的经验值大于A[i]。因此,根据乘法原理,第i个人当裁判时有num1*(i-1-num1)+num2*(原创 2015-03-19 12:19:14 · 785 阅读 · 0 评论 -
最大公约数和最小公倍数 UVa11388
1.题目描述:点击打开链接2.解题思路:本题通过观察发现,如果两个数a,b的最大公约数是G,那么G≤a且G≤b。因此直接令a=G即可。如何判断是否有解呢,只需要看是否满足gcd(G,L)==G就行了。如果满足,b=L。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#include#include#i原创 2015-05-20 15:50:08 · 561 阅读 · 0 评论 -
2.2 立方数之和 UVa11137
1.题目描述:点击打开链接2.解题思路:本题利用递推关系解决。建立一个多段图,定义状态d(i,j)表示“使用不超过i的整数的立方,累加和为j”的方案数。那么根据加法原理,如果没有选择数字i的立方和就得到了j,那么方案数就是d(i-1,j);如果选择了数字i的立方和才得到了j,那么方案数是d(i,j-i^3)。即:d(i,j)=d(i-1,j)+d(i,j-i^3);这个递推式还可以降低原创 2015-05-19 20:10:01 · 891 阅读 · 0 评论 -
最小公倍数 UVa11889
1.题目描述:点击打开链接2.解题思路:本题要求寻找最小的B,使得lcm(A,B)=C。这里容易想当然地认为B=C/A就是答案。实际上是错误的做法。因为lcm(A,C/A)不一定等于C,如果想让lcm(A,C/A)==C,必须有gcd(A,C/A)==1。通过恒等式a*b==gcd(a,b)*lcm(a,b)即可证明。这就提示我们得到临时的B之后,要想办法将A,B变为互素的两个数。还是利用恒等原创 2015-05-20 15:53:47 · 737 阅读 · 0 评论 -
排列之和 UVa11076
1.题目描述:点击打开链接2.解题思路:本题利用平均数的思想解决。由于每个数出现在任何一位的总的次数都是相同的,因此可以等效为它们的平均数出现的次数,而出现的次数就是重复排列的组合数,最后再乘以n个1即可得到答案。比如一个序列是{1,1,2},那么平均数就是(1+1+2)/3=4/3。出现的次数就是P(3,3)/P(2,2)=3,一共有3个1,那么ans=(4/3)*3*111=444。3原创 2015-05-22 11:19:37 · 1122 阅读 · 0 评论 -
LCM的个数 UVa10892
1.题目描述:点击打开链接2.解题思路:本题要求统计有多少个a,b,使得lcm(a,b)=n,其中n是给定的一个整数。不难发现,这里的a,b一定都是n的约数。根据题目给定的范围,不妨事先计算出所有的约数,。接下来利用二重循环枚举约数即可。注意:由于还要满足a≤b。那么只需要算出不超过sqrt(n)的所有约数即可,剩下的部分可以根据约数的对称性得到。这样的约数肯定不超过1000个,时间可以承受。原创 2015-05-22 10:35:37 · 828 阅读 · 0 评论 -
组队 UVa11609
1.题目描述:点击打开链接2.解题思路:首先选择一个人当队长,有n种选法;对于每一个队长,剩下的可以有0,1,2,...n-1个人,一共有2^(n-1)种情况。答案就是n*2^(n-1)。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#include#include#include#include原创 2015-05-22 11:33:03 · 638 阅读 · 0 评论 -
幂和阶乘 UVa10780
1.题目描述:点击打开链接2.解题思路:本题利用唯一分解定理及n!的指数的计算公式解决。可以想象,如果我们把m写成若干个素数乘积的形式,那么m^k就相当于对每一个素数的指数都乘上k。因此k实际上取决于幂次最大的那个素数。那么如何求解p^k'恰好整除n!时候的指数呢?可以利用数论中的定理k'=[n/p]+[n/p^2]+[n/p^3]+...。由于后面无穷项都是0,因此这是一个有限值,可以通原创 2015-05-22 10:25:53 · 1270 阅读 · 1 评论 -
全加和 UVa10943
1.题目描述:点击打开链接2.解题思路:本题实际上就是求x1+x2+...+xk=n的非负整数解的个数。根据组合数学的结论,答案是C(n+k-1,k-1)。可以事先预处理算出所有的组合数。3.代码:#define _CRT_SECURE_NO_WARNINGS #include#include#include#include#include#include#include原创 2015-05-22 10:22:10 · 828 阅读 · 0 评论 -
超级幂 UVa11752
1.题目描述:点击打开链接2.解题思路:本题要求找出1~2^64-1之间所有的超级幂。根据题意,不难知道这样的数的幂次一定是一个合数。而最大的幂次肯定不超过64,因此只需要去除4~64之间所有的素数即可,而这些素数可以事先打表。接下来开始枚举底数和幂次。由于幂次最多只有不超过60个,每个幂次对应的底数不超过10^5个,因此时间复杂度可以承受。但这里还有一个问题:如何知道枚举到哪个幂次就停止原创 2015-05-22 10:45:41 · 2491 阅读 · 0 评论