hdu
DickensTone
这个作者很懒,什么都没留下…
展开
-
hdu 1686
题意:给一个W串和一个T串,问W串在T串中出现了几次?思路:利用KMP,即可方便的找出第一次W串在T串中出现的位置。假设此模式串最后一位是j。next[j],即是在模式串中可以替代j的位置。继续匹配就好。需要注意的是,在生成next数组的时候,不要把w[j]==w[next[j]]的情况直接next[j] = next[next[j]]。 #include<i...原创 2018-08-26 18:31:09 · 162 阅读 · 0 评论 -
hdu 2766
题意:给一个天平,它可能不是平衡的,你可以修改砝码的值来使得它平衡,求最小的修改数量。我一开始也没思路,看了别人的也恍然大悟。我们可以通过天平末端的一个砝码的质量来求出整个天平平衡的重量。比如上图:知道了A的质量,那么天平的平衡重量为A*2 * 2。知道c的话为C * 2。我们可以利用每个砝码得到的值来计算出,最多有多少个砝码不用修改。#include#include转载 2017-10-14 09:31:28 · 197 阅读 · 0 评论 -
hdu 3714
参考厚白书题意:求出F(x)的最小值。x的取值范围为[0, 1000]。F(x) = max(Si(x))。Si = ai * x *x + bi * x + ci。其中ai恒定>= 0。也就是求0 -> n - 1 的每个Si的最小值,再在每个最小值之中取最大值。因为ai恒大于零,所以Si必定能用三分法求出。因为F(x)=max(S0, S1, S2, S3.....) i = 0转载 2017-10-28 11:31:42 · 219 阅读 · 0 评论 -
uva 1382
题意:找一个矩形,使得矩形的边上拥有最多的星星。输出星星的数量。这一题依旧用维护的方法做。l[i]为竖线i左边上下界上的点。on[i]为竖线i上,不在上下边界的点的数量。on1[i],则包含上下边界。如直线a,b。on的话为1,on1为3。那么矩形abdc边界上点的数量为l[AB] + on1[AB] + on[CD] - l[CD]。说起来,细节还是挺多的,参考厚白书。原创 2017-10-10 16:50:30 · 285 阅读 · 0 评论 -
hdu 4099
一道字典树的应用。这一题做起来,想要AC还是需要扎实的功底啊。我做起来就感觉,到处都不踏实,那就好好捋一捋。首先,斐波那契数的计算,这个就没弄好,先贴公式f(0) = 0, f(1) = 1, f(n) = f(n - 1) + f(n - 2)。那么为什么这一题输入1,输出却是0。那么肯定是f(0) = 1, f(1) = 1。(纯属猜测)计算数列的时候,也感觉不好下手,如果是用一个原创 2017-09-30 09:53:27 · 291 阅读 · 0 评论 -
hdu 1972
这题太水了,一个暴力模拟就A了。排队时,若是权值递增,那么最坏的情况是n!。可拍,可是n最大100。/**TASK: crypt1LANG: C++ID: DickensTone**/#include#include#include#include#include#includeusing namespace std;cons原创 2017-09-29 10:47:33 · 294 阅读 · 0 评论 -
hdu 1050
题意:给你一块地方,找出最大的空白矩形区域。金额是最大区域的三倍,输出金额。这一题就是找最大的矩形面积。一开始拿到,完全没有思路,唯有暴力?参考厚白书,暴力会GG。它的做法是算出每个块所在的面积,每次都算,当然不是维护就可以了。left[i][j]表示i,j这个块的最左点。同理:up[i][j], right[i][j]。怎么维护呢,如果这个点被占用,那么up[i][j] = 0。原创 2017-09-29 09:48:29 · 213 阅读 · 0 评论 -
hdu 6047
思路出自此。点击打开链接 。 这题我看到很多维护用的是线段树,但是这个博主给了我很多提示。(其实是我不会线段树-_-)题意:给出一个数n, 和数组a[1 -> n], b[1 -> n]。要求你求出a[n + 1 -> 2 * n]的和的最大值。要求:对于每一个a[i]],你必须从b数组中选择一个数bk,来推出它。a[i] i - 1]。b数组中的数,每个只能选一次。好,我们知道了ai转载 2017-09-20 21:00:13 · 197 阅读 · 0 评论 -
hdu 1800
不怎呢会哈希,自己差不多弄了个。开始WA, 把mod的值改了AC了/*PROG: gift1LANG: C++ID: grttman1 (<-- or C++11 if you prefer)*/#include #include #include #include #include using namespace std;const int m原创 2017-09-01 20:56:49 · 377 阅读 · 0 评论 -
hdu 6045
题意:有n道题,每一题一分。给出两个人的分数x, y和他们的选项,判断分数是否合理。这一题看似简单,实际上也很简单。首先,我们想一想。两个人的分数差距来自哪里?没错,来自他们不同的选项。如果选项相同,那么是不会造成分数差的。选型不同一定会造成分数差吗?不一定,但一定的是分数差d 偷偷看了看别人的,除了分数差需要考虑之外,还需要考虑的是总分。你想两个人有7个选项,其中5个不同,那么他们的原创 2017-09-19 11:46:15 · 414 阅读 · 0 评论 -
hdu 2769
这个题参照紫书的代码,暴力应该就ok了,谁知道还是出了很多问题。在一开始,就不明白题意,只能说很多字都很重要比如:* One line containing an integer n (0 ≤ n ≤ 10000):an input testcase. 和 followed by the sequence x1, x3, x5, ..., x2T-1 to the input fil原创 2017-09-18 21:43:02 · 471 阅读 · 0 评论 -
hdu 2492
题意:有一群乒乓球爱好者住在一条街上,他们的位置是依次从西往东。他们之间经常比赛,每次比赛需要一个裁判,裁判的能力必须在他们的能力之间且要住在他们之间。每个球员的能力都不一样,问:这条街能有多少种不同比赛(选手或裁判不一样)。球员的能力依次为A1-----An。那么若选Ai作为裁判,在1---------i - 1之间有Ci个人的能力Ai小,那么有I - 1 - Ci个人的能力比Ci大。同理:原创 2017-11-03 09:34:28 · 221 阅读 · 0 评论 -
hdu 1502
题意:给一个n,求出一个长度为3n,由A,B,C组合而成的字符串的种类数。组合条件:1。字符串中个数:A= B = C2。字符串的任意前缀,数量A >= B >= C。我们可以用动态规划来做,dp[i][j][k]表示,此字符串中A的数量为i,B的数量为j, C的数量为k。那么dp[i][j][k] = dp[i - 1][j][k] + dp[i][j - 1][k] + dp[原创 2017-12-10 20:23:54 · 264 阅读 · 0 评论 -
hdu 2601
给一个n,求出有多少组i,j满足 n = i * j + i + j (0 式子变形 n = i * (j + 1) + j + 1 - 1 = (i + 1) * (j + 1) - 1。 改变一下i,j的取值范围。 n + 1 = i * j (1 接着便可以用暴力找出所有的i( #include#include#includeusing namespace s原创 2018-02-07 18:45:14 · 211 阅读 · 0 评论 -
hdu 5475
题意:给一个数x和M,要对它进行两种操作。1是乘法,2是除法。1后面接一个数,表示x乘以该数。2后面接一个数y,表述x除以第y步的数。每一次操作后,输出x % M。这个题,数值很大。又有除法。而且要找一种能够把值保存起来,又能方便修改,又能快速查找一段连续序列的乘积。所以,线段树是一个很好的选择。我们把树叶末端(因子),保存为数值。(注意的是,我们一直要取模,所以除法要先把值除掉,原创 2018-02-03 21:33:41 · 214 阅读 · 0 评论 -
hdu 1051
题意:需要处理一些木棍。当处理第一根棍子时,需要 1 的准备时间。若之后处理的棍子,在长度和重量都大于刚刚处理过的棍子。那么不需要准备时间。问:需要最少的时间是多少。我们要计算的是,最小的准备时间。怎样才能使准备时间最小呢?当然是使当前处理的木棍的长度和重量都尽量的小,这样下一根木棍就有更大的可能直接处理。对了,就是贪心。我们可以排序,把木棍的长度和重量排序。这样选择的时候就保证了我们已经在为原创 2018-01-13 11:22:00 · 370 阅读 · 0 评论 -
hdu 1551
题意:给你n条电缆,分成k截,每截最长是多少?找一个长度,判断它能产生多少截绳子。没错,二分法。需要注意的是,输出的时候要小心四舍五入是不行的。(长度超长,不会产生相应的绳子)#include#include#includeusing namespace std;const int maxn = 10000 + 5;const double eps =原创 2017-12-07 11:59:40 · 314 阅读 · 0 评论 -
hdu 1513
题意:给你一个长度为n的字符串,求出最少加多少字符才能使成为回文串。我们可以把str1倒过来,得到str2。那么str1和str2的Lcs就是他们之间的最大不需要修改的值。也就是说,那些值原本是不需要动的。只是因为缺少一些必要的字符,只要加上他们str1就和str2相等了。n - LCS的长度,就是缺少的必要字符的值,就是答案。#include#includeusing原创 2017-12-06 21:46:50 · 154 阅读 · 0 评论 -
hdu 3926
题意:给你n个小朋友,和m个操作。操作就是让两个小朋友手牵手。然后再给n给小朋友,和m个操作。问:他们组成的结构是一样的吗。结构的形状有两种,圈和链。我们需要注意的是,判断他们的结构是否相同,我们可以判断的条件有,结构的类型,圈和链就不一样。然后是大小,这个可以根据人数来判断。这个题可以用并查集来实现。如果他们之间产生了相同的祖先,那么他们形成了圈(注意,只有两种形状)。人数就好判原创 2017-12-05 21:35:36 · 297 阅读 · 0 评论 -
hdu 1074
题意:有n门功课,每一门需要c天完成,若在d天还没有完成,之后每一天直到完成,会被扣分数。一题dp。用的状态压缩,因为最多15门功课。所以我们可以从1枚举到1用&判断此功课是否在当前枚举量中存在,若存在,便可寻求当前的最优解和跟新父节点。每一次状态的改变都是在枚举量变化之后,所以从前开始改变功课当前的状态,还是从后开始,并不影响答案。#include#include#inc转载 2017-11-24 10:51:10 · 143 阅读 · 0 评论 -
hdu 1559
一题dp我们要考虑的是如何求出矩阵的值。dp[i][j]表示从第一行,第一列开始,i行,j列的矩阵和。那么dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i-1][j-1] + num[i][j]。我们更新dp数组时,是从上到下,从左到右一个值,一个值更新的。那么我们dp[i - 1][j] 和dp[i][j - 1]都是早已算出,两个矩阵相加减去公原创 2017-12-11 21:22:48 · 245 阅读 · 0 评论 -
hdu 2818
题意:有N块转, 有两种操作。M x y:把x所在的砖堆放在y所在的砖堆上 C x:输出砖x下面的砖的数量这种一堆,一堆的很明显是并查集,不过带权。那么我们需要考虑,合并时,把x的根作为父节点还是y的根作为父节点。因为是输出每一块砖下面的砖的数量,所以,我们应该以下面为父节点,因为我们需要更新的是上面的砖,而下面的砖的状态是不变的。#include#include#in原创 2017-12-02 11:14:10 · 272 阅读 · 0 评论 -
hdu 1003
一道dp。思路:对于序列中的一个点i,有两种考量一是继承前面的序列和二是自己开始最关键的点在于,之前的序列和是否大于或等于0。若是小于零,对于点i来说,之前的完全没有用。所以:dp[i] = max(dp[i -1] + num[i[, num[i])。#include#include#includeusing namespace std;const int maxn原创 2017-11-22 21:35:47 · 129 阅读 · 0 评论 -
hdu 6033
在水题上栽跟斗啦,数学意识差了-_-计算2^m - 1 的 位数n。 再输出n - 1, 就是最大的10^n啦。2^m - 1 = 10^(a + b) ,b为小数,a为整数。其中a就为n - 1了。log10(2^m - 1) = log10(10^(a + b)) -> a + b = log10(2 ^m - 1) - -> a = log10(2^m)。/**PROB:转载 2017-09-18 16:18:38 · 393 阅读 · 0 评论 -
hdu 1251
一道字典树,并不难。坑的是c++与g++的区别,我也没搞懂。但是g++交oj是MLE。#include#includestruct node{ node *nex[27]; int cnt; node() { memset(nex, 0, sizeof(nex)); cnt = 0; }};void build_原创 2017-08-31 21:11:39 · 250 阅读 · 0 评论 -
hdu 1247
字典树。关于字典树,这个博客把这道题讲的很好。点击打开链接这里这个图很好#include#includeconst int maxn = 50000 + 5;char words[maxn][100];struct node{ bool is; node *nex[27]; node() { is = false;原创 2017-08-31 20:17:59 · 181 阅读 · 0 评论 -
hdu 1181
并查集 + 拓扑排序。拓扑排序具体怎么用还要学习,这个题里面就是从入度为零开始算起。一次只有一个入度为零,若大于一,则UNCERTAIN 如果执行完毕,还有数字没被计算,那么有环,则CONFLICT;#include#include#include#includeusing namespace std;const int maxn = 10000 + 5;struct no原创 2017-08-27 16:29:17 · 301 阅读 · 0 评论 -
hdu 1558
计算几何,对我来说超级难。本来是练并查集的。这题的难点在于判断两条线段是否相交,利用向量的叉乘可以判断两个点是否在线段的两侧。点击打开链接这里有判断的推导。#include#include#includeusing namespace std;const int maxn = 1000 + 5;struct point{ double x, y;};struct l原创 2017-08-27 11:13:44 · 302 阅读 · 0 评论 -
hdu 1325
就是一个简单的并查集。注意树的特点和要求。#include#includeconst int maxn = 10000 + 5;//最坑的是没有给出范围。int fa[maxn];int g[maxn];int root(int x){ if(x != fa[x]) { fa[x] = root(fa[x]); } return fa原创 2017-08-26 11:41:57 · 262 阅读 · 0 评论 -
hdu 1619
一道dp, 和那个数字三角有点像,只不过要记录路径。用一个nex数组(使用next会编译错误)来记录(i, j)下一列应该到的行.#include#include#includeusing namespace std;const int maxn = 10 + 1;const int inf = 1000000;int G[maxn][100 + 5];int nex[maxn][1原创 2017-08-22 22:07:53 · 235 阅读 · 0 评论 -
hdu 2514
一个简单的dfs,在没有重复的填完数字后再用ok检验。之前我用错,造成很多无解。#include#include#includeusing namespace std;const int maxn = 10;int num[maxn];int vis[maxn], cnt, ans[maxn];int ok(){ if(abs(num[0] - num[1]) != 1 &原创 2017-08-22 17:29:42 · 189 阅读 · 0 评论 -
hdu 2821
一道dfs, dfs都比较麻烦,没办法。 注意限制条件,在它可不是来回弹得哦。#include#include#includeusing namespace std;const int maxn = 25 + 2;int G[maxn][maxn];int row, col, x, y, sum;int ans[maxn * maxn], tot;const int dir[][2原创 2017-08-21 13:53:42 · 187 阅读 · 0 评论 -
hdu 1104
其实这题主要难在数论。难啊难。多看看别人的思路点击打开链接点击打开链接#include#include#include#include#includeusing namespace std;const int maxn = 1000 + 5;struct node{ int num, step; string road;}beg;int vis[maxn];i转载 2017-08-17 23:10:04 · 186 阅读 · 0 评论 -
hdu 1010
百度一下奇偶剪枝,看一下这个博客应该没问题了点击打开链接#include#include#include#include#include#includeusing namespace std;const int maxn = 7 + 1;char G[maxn][maxn];int n, m, t, ex, ey;struct node{ int x, y, step转载 2017-08-17 12:31:27 · 174 阅读 · 0 评论 -
uva 1608(分治 + 中途相遇法)
参考紫书,利用stl map,找到数组中相同元素的关系。每找到一个所求范围唯一元素,对元素所在的范围进行分治。转载 2017-08-16 20:55:04 · 337 阅读 · 0 评论 -
hdu 2774(滑动窗口)
这个思路和代码是参考紫书。保存数的长度为s + n + s + 1。这样能保证窗口可以从第一个数开始滑,可以求出所有情况(有例外,就是第三组数据类型)。以第一组数据为例,数组为 -1,-1,-1,-1,3,4,4,1,3,2,1,2,3,4,-1,-1,-1,-1。窗口长度为s = 4。从第一个数开始滑,判断此窗口合法性,并进行有效数的数量调整,下一个窗口可据此判断。接下来,只需统计滑动的可能性就性了。转载 2017-08-16 15:42:50 · 389 阅读 · 0 评论 -
uva 11584
一道dp。如果字符串的长度为len,则从1 -> len 判断此长度最少能有多少个回文串。判断是否为回文串利用了记忆化,若果此前已经确认过它是否为回文串,直接返回结果便可。#include#include#includeusing namespace std;const int maxn = 1000 + 5;char s[maxn];int vis[maxn][maxn];int原创 2017-08-28 09:08:59 · 255 阅读 · 0 评论 -
hdu 1856
一个简单的并查集,唯一的可能wa的点是考虑只有一个人的情况(0对朋友,可以选一人)。#include#include#includeusing namespace std;const int maxn = 1e5;int num[maxn], cnt[maxn];int pre[maxn], n, ans;int root(int x){ if(x != pre[x])原创 2017-08-28 21:52:09 · 258 阅读 · 0 评论 -
hdu 2059
一道dp题,把问题分解为,到达每一个站点需要多少时间。到达一个站点的时间为dp[n],那么计算dp[n]之前dp[1 -> n - 1]应都为已知。那么记得把充电的时间算入(第一个不计)/** PROG:milk2 LANG:C++ ID:DickensTone**/#include#include#include#includeusing namespac原创 2017-09-17 09:56:35 · 290 阅读 · 0 评论 -
hdu 3038
一道并查集,有对于我比较复杂的地方。看了他们的题解强行理解。利用并查集,用sum【集合的尾数】保存集合的和,合并的时候选小的(左)为父节点。这样遇到边界一样的集合,就可以判断是否冲突。#includeconst int maxn = 200000 + 5;int sum[maxn];int pre[maxn], ans;void init(int n){ for(int i原创 2017-08-30 19:30:11 · 327 阅读 · 0 评论