
ACM-高效算法
路小白_zZ
这个作者很懒,什么都没留下…
展开
-
uva 1335
题意:有n个人围成一圈,每个人都有想要ri个不同的礼物,每个人和相邻的两个人的礼物种类不能相同,问最少要多少种礼物才能符合要求。题解:这题不太好想出解决方法,看书上的题解,如果是n偶数,结果就是相邻两人礼物数之和的最大值,这个很好想,因为可以交替的把不同的礼物给两个人也不用担心会重复,而这个最大值刚好是满足条件的下限。但如果n是奇数需要二分出答案,L就是刚才的最大值,而R为了能减少二分次数定为原创 2015-01-31 14:45:12 · 946 阅读 · 1 评论 -
uva 11134(暴力)
题意:有n个车放到n*n的矩形内,任意两个车不在同一条竖线或横线上,且给出了每辆车在矩形内的范围,问是否有一种方法可以使n个车都有位置摆放,输出所有车的位置,否则输出IMPOSSIBLE。题解:像n皇后问题,但因为n的范围是5000,所以肯定不能dfs,那就要排序,把所有车先根据x的范围按从小到大排序,然后每行只能摆放一辆,如果做不到就IMPOSSIBLE,然后按y的范围从小到大排序,每列只能原创 2015-03-05 18:05:16 · 539 阅读 · 0 评论 -
uvalive 4725(贪心 + 二分)
题意:有两个飞机场,一个飞机跑道,每个时刻要两个飞机场中飞走一架飞机,有n个时刻,给出了每个时刻两个飞机场增加的飞机数量,每个飞机场的飞机都从0开始编号,问n个时刻后两个飞机场中飞机最大编号最小是多少。题解:最大值最小,二分,在判断函数中,五个变量,sumw、sume表示两个飞机场一共会有多少飞机,num表示会飞走多少架飞机,numw、nume表示两个飞机场可以各飞走多少架飞机,那么整体判断如原创 2015-03-06 21:45:54 · 948 阅读 · 0 评论 -
uvalive 4850(贪心)
题意:有n个任务,每个任务都有完成时间和完成期限,惩罚值就是超出期限的时间,问所有任务完成的最大和第二大惩罚值之和最小是多少。题解:先排序,期限越小的排前面,否则就时间短的先完成,但只这样不一定是最优解,可以牺牲某个任务使最终解更优,所以将牺牲掉任务的位置放到之前得到的第二大惩罚值的前面,这样可以使最大惩罚值减小,遍历之前的所有任务,更新最小值。#include #include us原创 2015-03-10 23:57:45 · 911 阅读 · 0 评论 -
uvalive 4851
题意:有n个餐馆,其中两个餐馆a,b还是宾馆(纵坐标相等),在m*m的矩阵上建餐厅p,如果位置好,对于已存在的餐厅q(包括a和b),就会有dist(p,a) 题解:直接暴力肯定超时,可以考虑一列一列的考虑,让A横坐标更小,从A的横坐标开始,到B的横坐标内所有位置有可能是好位置,然后计算出每列上已有餐厅到A的纵坐标最小距离存到d[i],然后从左到右更新一遍(每向右移动一次,最小距离就和前一列原创 2015-03-28 21:26:15 · 981 阅读 · 0 评论 -
uvalive 4094(贪心)
题意:有n个队伍要比赛,每两个队伍比两次,赢一场得3分,平一场得1分,输一场不得分,成为梦之队的条件:进球数最多(无并列)且丢球数最少(无并列)且胜利场数最多(无并列),问梦之队最低排名。题解:让梦之队排名低,有一种情况是梦之队只赢两场,剩下队伍只赢一场并且不输,那么梦之队最后得分n - 3,而剩下的队伍得分是2n - 1(梦之队赢的队伍)或2n,如果n - 3 ->n > 3,n -原创 2015-03-11 20:38:33 · 690 阅读 · 0 评论 -
uvalive 4726(单调队列)
题意:有个n长度的01序列,要求选出长度最短为l的子序列使这个子序列的平均值最大,输出开始位置和结束位置。题解:平均值是1的个数除长度,那么可以看做平面上已知个n点,求横向距离大于等于l的任意两点连线的最大斜率,所以用单调队列来解决,让队列中所含值保持单调,否则出队,并保证队首最优。#include const int N = 100005;int sum[N], q[N], n,原创 2015-03-29 14:19:00 · 794 阅读 · 0 评论 -
uvalive 3266(贪心)
题意:田忌和齐王赛马,每个人有n匹马,给出了这2*n匹马的速度,速度大的赢,赢一场赚200两银子,输一场赔200两银子,问田忌最多赢多少银子。题解:田忌赛马故事都听过,下等马对上等马,上等马对中等马,中等马对下等马,赢两场输一场,根据这个思路,先排序,然后如果田忌下等马可以赢齐王下等马,或田忌上等马可以赢齐王上等马,就直接res += 200,否则就让田忌下等马对齐王上等马,如果下等马和上等马原创 2015-03-11 17:00:18 · 811 阅读 · 0 评论 -
uvalive 4356
题意:有n个点在平面直接坐标线,给出了n个点坐标,然后问以(0,0)为圆心的扇形包含至少k个点最小面积。题解:贪心,先把所有点按与x轴正半轴的角度排序,然后选出一个点当半径,枚举剩下点(半径小于第一个点),更新最小面积值。#include #include #include using namespace std;const int N = 5005;const double原创 2015-03-29 22:43:03 · 720 阅读 · 0 评论 -
uva 11195(状态压缩+dfs)
题意:n皇后问题,'.'可以摆放,'*'不可以摆放,问有多少种摆法。题解:普通做法会超时,要用到状态压缩,每行能摆的位置标记为0,不可以的地方标记为1,然后深搜,参数有当前行数,和列、左对角线、右对角线不可以摆放的位置标记数,然后把当前行所有可以摆放的位置都递归下去,计方法数。#include const int N = 20;int m[N], n, res, all;char s原创 2015-03-05 17:12:53 · 621 阅读 · 0 评论 -
uvalive 4328(贪心)
题意:有n对夫妻要举行婚礼,然后一个牧师需要在所有婚礼上举行一个仪式,每个仪式必须占用婚礼一半以上的时间且不能被打断,给出了n个婚礼的开始和结束时间,问是否可以让牧师在所有婚礼都举行仪式。题解:先按婚礼起始时间排序,然后遍历所有婚礼看是否有足够时间举行仪式。#include #include using namespace std;const int N = 100005;st原创 2015-03-25 19:00:18 · 587 阅读 · 0 评论 -
uva 11627(二分)
题意:有一个人滑雪过门,有n个门,给出了每个门的位置和宽度,然后给出了一个人的水平速度最大值,有S双滑雪鞋,穿每种不同的鞋会有不同的竖直速度,起点和终点任意位置,问能按顺序穿过所有门的最大竖直速度是多少。题解:二分出最大的竖直速度,根据距离和水平速度,计算出左右边界,如果和下一扇门有交点,就得到下一扇门的左右边界,如果可以通过最后一扇门就ok了。#include #include us原创 2015-03-03 20:04:24 · 663 阅读 · 0 评论 -
uva 1346(贪心)
题意:有n首歌,有各自的编号,长度,频率,给出一种排列方式要重新排列这些歌,问排列后第s首的编号是什么。题解:排序方式是长度越短频率越高的排在前面。#include #include const int N = 70000;using namespace std;struct Song { int id, l; double fre;}song[N];int n, s;原创 2015-02-03 23:54:44 · 717 阅读 · 0 评论 -
uva 11549(floyd判圈)
题意:有一个计算器上只能显示n位数字,输入k,然后不停平方,直到溢出时显示的是高n位的数字和错误标记,然后把高n位数字继续平方,问计算器上显示的最大的数字是多少。题解:多试几次发现结果都是循环的,所以模拟一次循环找最大值,floyd判圈算法,一开始k1、k2都等于k,k2做两次平方而k1做一次平方,一旦k2 == k1说明循环了一次,就可以停止了。#include #includ原创 2015-02-07 21:44:34 · 692 阅读 · 0 评论 -
uvalive 2678
题意:给出一个长为n的序列,和目标值s,找出最短序列和刚好大于等于目标值,输出序列长度。题解:枚举起点终点时间复杂度高,可以枚举终点,f[i]表示序列第1个到第i个数字的和,因为f数组递增,可以用lower_bound()找到起点的位置,使复杂度降低。#include #include using namespace std;const int N = 100005;int f原创 2015-02-09 00:08:51 · 698 阅读 · 0 评论 -
uva 11462
题意:把给出的数从小到大输出一遍。题解:数很多但范围小,可以用计数排序,m[i]存数字i的数量。#include #include const int N = 105;int m[N], n;int main() { while (scanf("%d", &n) && n) { memset(m, 0, sizeof(m)); int a, flag = 0; fo原创 2015-02-07 20:50:32 · 610 阅读 · 0 评论 -
uva 11292
题意:有n个龙的头,和m个骑士,每个骑士可以砍掉不超过其能力值x的龙的长度的头,且要雇佣这个骑士就要交x,那么最少的雇佣费是多少,每个骑士只能被雇佣一次,且只能砍一个头。题解:龙头的长度和骑士能力值都从小到大排个序,然后贪心得到最少的雇佣费。#include #include using namespace std;const int N = 20005;int n, m, dra原创 2015-01-23 18:03:24 · 554 阅读 · 0 评论 -
uva 11729
题意:有一个人给n个人安排任务,交代任务要b时间,执行任务要j时间,交代任务时必须一个一个人交代,但任务执行可以同时进行。问所有人任务完毕最少花费时间。题解:贪心思想,一个人执行任务时间越长应最先交代任务,所以只要按执行时间排序,然后交代时间累加与执行时间比较选出较大值就是结果。#include #include using namespace std;const int N = 1原创 2015-01-23 18:14:05 · 671 阅读 · 0 评论 -
LA 3708(贪心)
题意:有n个雕塑等距放在一个周长为10000的圆上,现在要再放m个雕塑,要使所有雕塑仍然保持等距,问n个雕塑最少移动总距离是多少。题解:让n个中的一个雕塑不动,作为原点,那么剩下的雕塑需要移动的位置就确定了,然后把圆周长按比例缩小为(n + m),只要把每个雕塑移动到和它最近的整数点位置就可以了。然后再将所有移动的距离按圆周长是1的比例缩小加起来。结果放大10000倍。#include原创 2015-01-24 23:21:14 · 648 阅读 · 0 评论 -
uva 11300(贪心)
题意:有n个人坐在圆桌上,每个人有初始金币m[i],金币总数能整除n,每个人可以给相邻的人金币,也可以得到相邻的人给的金币,问最少转手多少金币可以使所有人的金币数量相等。题解:最后每个人手上应该有sum / n个金币,设每个人i得到和失去的金币分别是x[i]和x[i + 1],那么可以得到所有转移金币是x1 、x1 - (m1 - sum / n)、x1 - (m1 + m2 - 2 * su原创 2015-01-24 23:31:14 · 656 阅读 · 0 评论 -
uvalive 4254(二分)
题意:有n个任务,给出了每个任务的起始时间和终止时间还有工作量w,处理任务的速度为s时,任务会花费 w / s时间,然后每个任务都要在规定时间内完成,但任务可以不用连续时间块内完成,要求出让所有时间都顺利完成的最大速度的最小值。题解:一般要求最大XX最小值时用二分法,可以二分出一个速度,拿去判断是否可行。在判断一个速度是否可以使任务完成时,用一个优先队列(终止时间小的排在前面)存所有未完成原创 2015-03-02 20:52:22 · 792 阅读 · 0 评论 -
uvalive 3716
题意:有两个长度是n的序列,找出一个[l,r]的区间,这个区间内有不超过%p的数满足A[i] != B[i],问区间长度最长是多少。题解:先扫一遍把每个字母从开头到现在的序列内不同字母的比例计算出来,然后按不同字母比例从大到小排个序,再扫一遍,更新最大长度。#include #include using namespace std;const int N = 150005;st原创 2015-03-30 22:11:21 · 918 阅读 · 0 评论 -
uvalive 5052
题意:有两个a和b的1到n的排列,统计a和b有多少个连续的子序列包含完全相同的整数集,子序列至少包含两个元素。题解:可以先记录b数组中每个数字的位置,然后枚举a数组的起点和子序列长度,然后用l和r限定范围,初值是a数组起点在b中的位置,因为是连续子序列,如果有更大范围出现就可以更新l和r,如果r - l == len,解的数量加1,。#include #include cons原创 2015-03-30 19:47:48 · 873 阅读 · 0 评论 -
uvalive 2757(贪心)
题意:有n个任务,给出了每个任务的奖金和期限,每个任务完成都要1个时间单位,问选择一些任务都按时完成可以得到的最多奖金是多少。题解:先按时间排序,倒着枚举所有时间点,给它分配奖金最大的且未被分配的任务。#include #include #include using namespace std;const int N = 10005;struct P { int pi, d原创 2015-03-24 21:33:14 · 805 阅读 · 0 评论 -
acdream 1224(贪心)
题意:有n个抢劫者抢劫了m块金子,然后第i个人平分xi/y块金子,但是会有除不尽的情况而金子不可再分,那么每个人都有一个不满意度fabs(xi / y - ki/m),ki是每个人实际分得的金子数量,要保证所有人的不满意度和最小,问ki应如何分配。 题解:如果可以除尽,ki就是xi * m / y,否则要把不满意度和再多分一块金子的不满意度的差值存起来,按从大到小排序,把多出来的金子数量num给前原创 2015-05-07 16:25:57 · 738 阅读 · 0 评论 -
poj 3579(二分)
题意:有n个数字,得到所有两两的差值的绝对值,从小到大排列后取中间的数字是多少,如果是偶数个,取中间靠左边的那个数字。 题解:如果是两层for一定会超时,先从小到大排序,用二分枚举差值x,然后计算从i开始往后的序列二分查找大于等于a[i] + x的数字的个数,把所有个数累加起来如果总个数大于n * (n - 1) / 4则继续增大差值,否则减小。#include <stdio.h>#includ原创 2015-05-20 21:56:51 · 610 阅读 · 0 评论 -
hdu 5248(二分)
题解:二分出最小代价x,然后倒着让每个数字都在x的变化范围内单调递减,如果无法实现就return false,左边界为x + 1,否则右边界是x。#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int N = 100005;long long原创 2015-05-30 19:06:21 · 1305 阅读 · 0 评论 -
poj 3258(二分)
题意:有牛要过河,河宽为l,上面有n块石头,要求拿走m块石头后,让相邻两个石头的最小距离最大(假设两岸也有石头但无法取走)。 题解:二分出距离然后拿去判断。#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;const int N = 50005;int l, n, m, pos[N];原创 2015-05-18 19:52:55 · 939 阅读 · 0 评论 -
poj 3111(二分)
题意:有n个珠宝,每个珠宝都有价值v和重量w,要保留k个珠宝,使得式子 中的s最大,求出s。 题解:想不出做法,网上一位童鞋的题解写的比较明白,http://m.blog.youkuaiyun.com/blog/yew1eb/38730447#include <stdio.h>#include <algorithm>using namespace std;const int N = 100005;i原创 2015-05-19 16:39:16 · 572 阅读 · 0 评论 -
poj 3273(二分)
题意:一个农场主计算出农场接下来n天每天的具体花费,并做了一个预算,在m天内用掉n天的钱,相当于把一天或连续多天的花费一天用完,问m天内最大值最小是多少。 题解:二分出钱数,然后判断是否可以m天内用掉n天的钱。#include <stdio.h>#include <string.h>const int N = 100005;int n, m, mon[N];bool judge(int x)原创 2015-05-19 17:37:56 · 386 阅读 · 0 评论 -
poj 3104(二分)
题意:有n个衣服要烘干,每件衣服都有含水量ai,每分钟衣服含水量都可以减少1,用烘干机每分钟含水量减少k,烘干机每次只能放入一件衣物,那么问最少几分钟可以让所有衣服含水量为0。 题解:先把含水量从大到小排序,二分出时间x,然后如果a[i] <= x,就不用烘干机,否则a[i] - 已过去时间 - k * 已使用烘干机次数 <= x - 已过去时间 - 已使用烘干机次数, 从而计算出这件衣服应该用原创 2015-05-19 21:59:27 · 775 阅读 · 0 评论 -
uva 10037(贪心)
题意:有n个人要过桥,每次只能过一个或两个人,只有一个手电筒,所以如果还有人未过桥要有人把手电筒带回来,每个人过桥时间都不相同,问所有人过桥最少需要多长时间。 题解:贪心,有两种选择,一种是最快的人和次快的人先过桥,然后最快的人回来,最慢的人和次慢的人过桥,次快的人回来,另一种选择是最快的人先和最慢的人过桥,最快的人回来,最快的人再和次慢的人过桥,最快的人再回来,每次比较两种花费时间那个更短用哪个原创 2015-07-14 14:49:30 · 1005 阅读 · 0 评论 -
Codeforces 570B
题意:有A和B玩游戏,从1~n数字里,A选了m,B选了a,假设有一个数字c在1~n中,如果m离c更近或者m和a与c的距离是相等的,都是A胜,已知n和m,问a取多少可以让B的胜率最大。 题解:贪心,如果m在中间靠左,那么a = m + 1,如果m在中间靠右,那么a = m - 1,如果刚好在中间取左边,因为胜率相同取小值。#include <cstdio>using namespace std;i原创 2015-08-15 00:02:54 · 695 阅读 · 0 评论 -
poj 2976(二分)
题意:有一个式子是 给出n组a[i]和b[i],去掉k组,让剩下的a[i]和b[i]带入式子计算出的最大值是多少。 题解:和poj3111的思路类似,只不过这个要四舍五入,注意强制转换。#include <stdio.h>#include <algorithm>using namespace std;const int N = 1005;struct P { int a, b;原创 2015-05-20 17:08:03 · 663 阅读 · 0 评论 -
acdream 1212(贪心)
题意:有n个人,从1到n,编号越大职位越低,然后给出了第2到第n个人的上司的编号,每个人可以有一堆小弟但只能有一个上司。年底发奖金,每个人可以从上司那得到1000元或发给某个小弟1000元,问所有人能发的奖金和最大是多少,那些人得到了奖金。 题解:直接倒着遍历一遍,把人和他的上司标记掉算作一组,看有几组。#include <stdio.h>#include <string.h>const in原创 2015-05-07 18:52:44 · 837 阅读 · 0 评论 -
acdream 1716(贪心)
题意: Problem Description在ACdream王国中,有一条母亲河,这条母亲河为王国人民提供了各种生活用水。在河边共住着n户人家,每户人家的位置为x[i]。由于经济发展需要,ACdream决定在这条母亲河上建立一个水力发电站,经过勘测,这个水力发电站只可以建立在区间[a,b]的某一个地方x0。为了减少大家受到来此发电站的影响,希望min{|x[i]-x0| |0<=i<=n-1}最原创 2015-05-07 02:05:49 · 721 阅读 · 0 评论 -
hdu 5203(贪心)
题意:一个长为n的木棍又n个长度为1的小木棍组成,但有一些小木棍是坏的,给出了那些位置上的小木棍是坏的,现在要把长木棍切割成4条,要求其中3条都是不包含坏木棍且长度和最大,而且这3条好木棍可以组成一个三角形,问有多少种切割方式。题解:要3条都是不包含坏木棍,那么包含坏木棍的一条一定是左端是最左边的坏木棍,右端是最右边的换木棍,有两种情况,一种是左端点在头部或右端点在尾部,那么剩下的木条切两刀形原创 2015-04-12 00:18:45 · 815 阅读 · 0 评论 -
uva 669(贪心)
题意:有连续n块内存,然后有k个文件,每个文件可以分为ki块放到内存里,其他内存块为空,现在给出每个文件的ki个碎片在内存中的放在第几块(碎片有序),然后开始进行内存块内容的移动,操作a b表示把内存a中的东西放到内存b中,前提是b为空,要求最少的操作使文件能够按顺序从最小的内存块开始存储,输出顺序操作过程。题解:用一个flag[i] = j表示位置i上放的碎片应该放到位置j上,可以先遍历一遍原创 2015-04-23 20:55:54 · 709 阅读 · 0 评论 -
hdu 5037(贪心)
题意:有一只青蛙要过河,给出了河的宽度M,青蛙最多跳的长度L,现在有n块石头在河中,给出了n块石头的位置,青蛙只能跳在陆地或石头上,把河看做一条数轴,青蛙每次都会尽可能的跳的远,要让青蛙过河且让青蛙跳尽可能多,现在人作为上帝可以随意放石头在河中,问青蛙最多跳几步过河。题解:如果刚开始没有石头,那么先跳1再跳L是最多步数的跳法,所以可以设一个变量pre作为前一跳的长度,然后每次得出两个相邻石头距原创 2015-03-13 00:08:10 · 608 阅读 · 0 评论 -
acdream 1682(有环的最大连续和)
题意:有n个数字围成一个圈,然后从圆圈拿走连续的一些数,问拿走的数的和的最大值是多少。题解:普通最大连续和的做法,如果前面累加的数加当前数是大于最大值就更新最大值,如果小于0就把累加值清零,这个是有环的,那么可以从两种情况考虑,一种是普通的最大连续和找到的最大值,另一种就是头尾拼接的,把所有数取相反数,然后找到最大连续和,那么用总和sum加这个数就是头尾拼接的最大值,取两种情况较大的就是解。原创 2015-04-15 23:54:25 · 883 阅读 · 0 评论