Algorithm
文章平均质量分 74
MarchOrHome
这个作者很懒,什么都没留下…
展开
-
poj2114(树的点分治)
参考文章: http://blog.csdn.net/yang_7_46/article/details/9966455 题目的大致意思是要求出是否存在两点间的路径长度为K的情况 不知道为什么1741一直是re,主要还是看别人文章学习来的树的点分治。 点分治,主要是分类来进行处理,对于两点之前求距离可以分为两类情况: 1.过根节点(不在一棵子树内)原创 2015-05-27 16:01:25 · 374 阅读 · 0 评论 -
uva11361(数学题,记忆化搜索)
题目的大概意思是要找一种数字,要求这种数字对题目给定的K值有如下的作用: 首先该数字能被K整除,另外该数字的每一位数字和也能被K整除。 题目给定A,B,K,要求区间[A,B]中这种数字的个数。 做法就是搜索了f[i][j][k]代表后面还有i位,数除以K的模为j,每个位上数字和模K为k的个数。 然后,例如11361,首位为0时要求f[3][0][0],不过当首位为1时,后面原创 2015-06-13 15:45:59 · 546 阅读 · 0 评论 -
uva580(数学题)
题目大意是有n个盒子,每个盒子里面分别装的是U和L,然后当有3个或者大于3个的U在一块时,被叫做危险的组合,那么给一个数字n,要求它危险组合数的个数。 解答:f[i]表示有i个盒子时,危险组合的数目,分两种情况: 1.前i-1个盒子中已经出现了危险组合,那么第i个组合可以任意为U,L,个数为2*f[i-1]。 2.第i个盒子为U时,恰好出现了危险组合,那么最后三个就是为UUU,倒原创 2015-06-12 20:24:19 · 419 阅读 · 0 评论 -
uva12169(扩展欧几里得)
题目的大意是给你一个递推式Xi = (a*Xi-1+ b ) Mod 10001,然后告诉奇数项,要你求出偶数项。 解法就是枚举a,然后根据前两个奇数项算出b。 可以推出下面的式子: 然后因为gcd(a+1,10001) = 1,然后根据扩展欧几里得算出b来,随后再来验证,如果正确即为满足条件的解。 #include "stdio.h"#include原创 2015-06-12 16:47:28 · 337 阅读 · 0 评论 -
uva10820(简单数学题)
题目的大概意思是有两个变量x,y,然后x,y都是小于n的,有一个函数f(x,y),另外f(x*k,y*k) = f(x,y),问f(x,y)在x,y都不超过n的时候的取值个数,很明显的就是记下来的想x,y必定是互素的,当然有一个另外就是1,1。 求解,很明显的就是转化为欧拉phi函数问题,求出1-n中与n互素的个数,然后x,y可以互换位置,求得的结果要乘以2。 #include "st原创 2015-06-12 19:19:03 · 443 阅读 · 0 评论 -
uva11401(数学基础题)
题目的大意是:现在有1...n总共n个不同的数字,从里面任选三个作为三边长,能构成三角形的个数一共有多少个。 解答:设c(x)是最长边为x时的三角形个数,那么要求的答案就等于c(1) + c(2) + ...... + c(x),所以主要需要解决的是c(x),又设三边长分别为x,y,z,由x-y 1.当y = 1时,z有0个解; 2.当y = 2时,z有1个解; ....原创 2015-06-10 15:38:13 · 354 阅读 · 0 评论 -
uva11806(容斥定理)
题目的大意就是在一个m行n列的棋盘上放k颗棋子,要求是在第一行和最后一行,第一列和最后一列都有棋子,应该说分类的话,也可以做出来,但是比较繁琐,而且容易出错。 解答可以用容斥定理,分别设A,B,C,D为第一行没有棋子,最后一行没有棋子, 第一列没有棋子,最后一列没有棋子,答案就是在棋盘上,但是不在ABCD上的。 然后容斥定理计算即可,减去奇数情况的。 #include "stdi原创 2015-06-10 16:00:30 · 317 阅读 · 0 评论 -
poj(1260,动归)
做得最无语的一道题目。 题目的大概意思是你的采购单上需要n多级别的宝石,然后每购买一级的宝石,需要额外支付10个该等级宝石的钱,然后可以用更高等级的宝石代替低级别的宝石。 动归方程是f[i]表示前i等级所需的最低钱数为,那么动归方程是(a[i]表示第i级别需要的个数,p[i]表示第i级别宝石单价): f[i] = min(f[i], f[j] + ( a[j+1] +原创 2015-06-09 15:39:06 · 286 阅读 · 0 评论 -
poj2533(LIS)
没什么说的,纯裸的LIS,到是二分的感受更明白了点。 #include "stdio.h"#include "string.h"#include "math.h"#include #include #include #include #include #include #include using namespace std;#define MAXM 1#defin原创 2015-06-09 15:56:52 · 272 阅读 · 0 评论 -
uva11426(数学题)
题目的大概意思是给你一个n,要求gcd(1,2) + gcd(1,3) + ... + gcd(i, j) + ... + gcd(n-1, n), 1 先按照递推的思路,设f(n) = gcd(1,n) + gcd(2,n) + ... + gcd(n-1,n), 那么ans(n) = ans(n-1) + f(n), 所以题目的关键就是求f(n),求f(n)就是要找到n的约数,一个一个原创 2015-06-15 15:44:52 · 386 阅读 · 0 评论 -
LA3644(并查集,维护连通分量的集合)
题目的大致意思就是要拒绝会使图中出现环的边,用一个并查集来进行维护,如果是同一个连通分量中的就拒绝。 #include "stdio.h"#include "string.h"#include "math.h"#include #include #include #include #include #include #include using namespace原创 2015-07-14 15:59:02 · 386 阅读 · 0 评论 -
CF338(div2)
A. Bulbs题目描述:就是有m盏灯,有n个开关,一开始灯都是关的,然后按下一个开关后就会使某些灯打开,然后打开的灯不会再次熄灭。问能否是所有的灯打开。解答:简单的遍历一下,然后看是否存在有灯不受开关控制。#include using namespace std;int num[105], n, m;void solve(){ int cnt = 0; for原创 2016-01-13 15:36:53 · 403 阅读 · 0 评论 -
最小子段和,最大子段和,最小正子段和
最大子段和比较好求解,就是一个dp标记走就可以了,当dp最小子段和就是把所有的元素去相反数,然后在此基础上求一个最大子段和就好。主要想说的是最小正子段和的求法,是先算前i位的累加和dp[i],并记录标记为i。然后对所有的dp[i]进行小到大的排序,然后对两个相连的dp[i],如果后者的标记大于前者的标记,那么它们的差值是候选答案,然后选取候选答案最小的那个。PS:注原创 2015-12-16 10:17:25 · 2307 阅读 · 0 评论 -
2-SAT问题(LA3713)
主要是形成一个句子类似于 “A真(假)或B真(假)”,然后来建立一些边。 模板如下:struct TwoSat{ int n, S[maxn * 2], c; vector G[maxn * 2]; bool mark[maxn * 2]; bool dfs(int x){ if(mark[x ^ 1]) return false; if(mark[x]) return原创 2015-11-19 20:40:46 · 375 阅读 · 0 评论 -
uva11732(Trie)
Trie树的一道水题,根据系统的strcmp函数,求比较次数。 就是给你n个单词,让他们两两比较,要求他们运用strcmp时,进行比较的次数。 根据题目数据量的范围,肯定不能用简单模拟,然后就想到比较时建Trie树,关键是考虑怎么计数,例如than和that它们比较的次数就是7次,因为他们是在a之后出现不同,就是要记录比较结束的位置,来进行计算即可,那么我们就来一个va原创 2015-09-09 15:31:24 · 1075 阅读 · 2 评论 -
LA3942(Trie)
题目的意思是有一个词典,然后给你一个字符串,把这个字符串按照词典当中的单词划分,问有多少种划分的方法? 比较容易想到的方法是对这个字符串的每一位进行枚举,找出以当前位为开始的字符的单词个数既d[i+len(x)] += d[i];但是如果是这样的话,每次要枚举词典,那样时间复杂度太高,所以就用trie树来构建字典,然后单词的长度为100,那么每一位的枚举就是最多100次,所以时间复杂原创 2015-09-09 10:25:43 · 412 阅读 · 0 评论 -
uva11235(RMQ问题)
题目的意思是:有一个有序的数组,然后每次给出数组的两个端点L,R,要求出数组区间[L,R]里面出现最多的数字。 题目的解法:运用RMQ的思想求解即可,在求解之前需要转化一下模型,我们把这个数组可以转化为对于数字p,记录它的左端点位置nL[p],右端点位置nR[p],个数nV[p],对于每一次访问实际我们可以分三块来进行求解:首先是左端点num[L]的数字个数等于nR[num[L]] - L原创 2015-07-18 10:01:55 · 305 阅读 · 0 评论 -
LA4329(树状数组)
题目的大致意思是:有n个乒乓球手,然后他们都有一个能力值,然后需要每三个选手可以组成一场比赛,这场比赛要求,中间的那个人作为裁判,而且中间的人的能力值必须在两位选手之间,这个比赛才是合法的比赛,问这个这些选手一共能组织成多少场比赛? 解题思路:首先对单个人作为裁判进行研究,假设标号i的人,假设前面小于他能力值的人为C[i],那么前面大于他能力值的即为i - 1 - C[i],假设后面小于他能原创 2015-07-17 10:24:06 · 346 阅读 · 0 评论 -
LA3027(并查集)
就是并查集维护连通分量,找到祖先节点(即根节点),我的代码不好的地方,在于路径压缩后的距离更新没写好,应该可以采取后序遍历的方法写距离的更新,代码如下: int find(int v){ if(v != father[v]){ int u = find(father[v]); dis[v] += dis[father[v]]; return father[v] = u; }原创 2015-07-14 16:38:41 · 278 阅读 · 0 评论 -
poj1159(dp,最长公共子序列)
题目的大概意思就是给你一个字符串,然后可以往字符串里面插入字符,要计算出至少插入多少个字符,可以让它形成一个回文串。 做法就是生成一个新串,该新串是原串的逆序串,然后求两个串的最长公共子序列就好。 动归方程: dp[i][j] = max( dp[i-1][j], dp[i][j-1], dp[i-1][j-1] + ( s1[i] == s2[j] ? 1 : 0 ) );原创 2015-06-09 16:44:46 · 382 阅读 · 0 评论 -
poj3414(BFS)
就是一个很简单的BFS的题目,搜索出状态,看能否得目标状态,就是有六种操作,每种都记一下就好了。 #include "stdio.h"#include "string.h"#include "math.h"#include #include #include #include #include #include #include using namespace s原创 2015-06-08 15:58:54 · 240 阅读 · 0 评论 -
poj1094(拓扑排序)
好吧,这个题目的题意对于英语弱渣的我来说,略难懂,实际就是,每次读入一个信息,然后判断现在是否出现有环,或者出现唯一的拓扑序列,如果直到最后一条信息读完,都没出现前面两种情况,就说没有无法决定的拓扑序列。 wa了一发,主要原因是应该先判断是否有环,然后再来判断序列不唯一。 思路:就是每读入一条信息,就进行一次拓扑排序,得出结果。 #include "std原创 2015-06-01 16:05:36 · 287 阅读 · 0 评论 -
poj3020(二分图的最大匹配)
典型的二分图最大匹配的问题: 具体而言就是对里面的点分做两类,一类是横纵坐标之和是奇数的点,一类是横纵坐标之和是偶数点,只有这两类的点才能匹配,建边的原则是看它的四个方向和它本身是否是'*'号,然后答案就是所有为'*'的点减去最大匹配的值。 #include "stdio.h"#include "string.h"#include "math.h"#include #inclu原创 2015-06-02 15:03:25 · 245 阅读 · 0 评论 -
poj1035(简单题,串)
一个简单题,先看字典中是否存在该传,如果不存在,就跟字典中字符串的长度比较,长度的绝对差大于1时,必定不是候选的答案串,长度相等时,看是否只有一个字符错误;长度不等时,看是否可以通过较长串删除一个字符得到较短串。 #include "stdio.h"#include "string.h"#include "math.h"#include #include #include #in原创 2015-06-02 16:41:01 · 339 阅读 · 0 评论 -
hdu4857(反向拓扑排序)
折腾了一下午,一开始以为从1....n分别找出反向路径进行输出,然后就是正确的姿势了,提交了一两把,发现是错的,比如下面的case: 4 3 4 2 2 1 3 1 正解应该是4 2 3 1, 而我的是3 4 2 1,后面的2的位置明显靠后,然后看了想了一下符合反向拓扑排序的规律,所以建边的时候反着建就可以了。 当然输出也要是逆向的,这个时候借助一下栈就原创 2015-05-28 16:50:21 · 421 阅读 · 0 评论 -
hdu4885(最短路)
好吧,很好的题目,题目的大意是: 在一个平面上,有一个起点,一个终点,然后有好多加油站,每加一次油,可以走L公里,问最少要加多少次油? 还是太水,一开始没想到最短路,实际就是看做n+2个节点,每个节点对于它距离小于L内的节点,可以建一个权值为1的边,然后运行一下最短路就好了。 PS:巨大的坑点是,只要经过了加油站,就要加油,所以折腾了好久,不过也学习了一把处理斜率的方式。原创 2015-05-30 09:58:38 · 350 阅读 · 0 评论 -
hdu 4883
好吧,这题做法应该比我的好,好的做法是根据开始的时间排序。 然后开始遍历时间,遇到一个开始的时间,就加上当前的值,遇到结束的时候就减去这个值,在这个过程中的最大值就是题目的解。 自己的做法是看状态总共也就24*60种,就自己找到开始时间和结束时间,在这个期间的每个时刻加上当前值,然后找出值最大的时刻。#include "stdio.h"#include "string.h"#inc原创 2015-05-30 10:08:49 · 276 阅读 · 0 评论 -
高精度(还有其它的以后再补充)
只是实现了+,*,以及除以一个整数,其它遇到了就再补充。 struct BigData{ int s[105]; int len; BigData(int x){ Mem(s, 0); len = 0; while(x){ s[len] = x % 10; x /= 10; len ++; } } BigData(): len(0){ Mem(原创 2015-06-18 17:45:28 · 271 阅读 · 0 评论 -
uva11916(数学题,模方程)
题目的意思是有M*N列的格子,K种颜色,B个不能涂色的格子,涂色的约束条件是每一列相连的格子上不能是相同的颜色,然后总数Mod100000007的结果是等于R的,现在题目中告诉N,K,B,R,要求满足条件的最小M。 解答:根据B个格子的坐标,可以求出最小的行minM,然后求对于minM*N的格子有多少种方案,然后再往外扩展一行,又有多少种方案,假设求得Mod完之后的结果为a,那么往后每添加一原创 2015-06-16 15:29:26 · 490 阅读 · 0 评论 -
poj3080(简单题,串)
思路是二分长度(并没有太大的作用),然后kmp匹配,然后找出最大的串,如果有多个的话,要找出字典序最小的那个。 PS:这种找段落的,注意控制循环结束的条件。 #include "stdio.h"#include "string.h"#include "math.h"#include #include #include #include #include #include原创 2015-06-02 17:48:21 · 337 阅读 · 0 评论 -
poj1936(简单题,串)
本质就是一个简单的贪心匹配了,在第二个串中顺着找第一个串的每个字符就可以了。 #include "stdio.h"#include "string.h"#include "math.h"#include #include #include #include #include #include #include using namespace std;#define M原创 2015-06-02 19:54:49 · 378 阅读 · 0 评论 -
CF#309(Div2)C(组合数的数学题)
题目的意思是有N个数,分别为1-N,然后给出每个数的个数Ci,然后要求一种排列,排列必须满足最后一个i不能在最后一个i+1的后面。 解答的方法,就是先排最后一个1,其余的1必然在它的前面,再排最后一个2,那么它的前面就有C1 + C2 - 1个数,他们可以随便排列,就是有重复数字的个数,就为 再放3,就把前面的1,2看做整体,思路跟前面的是一样的,所以最后的就是所有的组合方式原创 2015-06-26 16:29:42 · 428 阅读 · 0 评论 -
poj3274(数的哈希)
特别好的一个题目,题目的大概意思是,每头牛都有一定的属性值,然后把这个属性值转化为一个二进制数,从右到左分别呢标号为1,2...N,如果某一位上为1,那么它就具有这个属性。现在定义一个区间是“balanced”,当它满足区间内每个属性出现的次数相同,要求这样的区间的最大长度。 分析:令sum[i][j]代表前i头牛j属性的个数和,那么balanced的区间(i,j)就满足 su原创 2015-06-04 11:09:01 · 284 阅读 · 0 评论 -
poj2513(trie树+欧拉路+并查集)
题目的大意就是一根木棍两端涂上颜色,然后要把所有的木棍连成一根木棍,然后两根木棍能合并的前提是,连在一起的两端是同样一种颜色,然后这个额就很好理解,是一边画问题,求是否有欧拉路出现就好。 无向图有欧拉路的条件: 1.有0个或者2个点的度数为奇数。 2.图是一个连通图。 然后判断图连通,就是运用并查集的方法,每次合并一条边的两个顶点,最终一个连通图会合并成一个顶点,一原创 2015-06-05 09:50:31 · 338 阅读 · 0 评论 -
POJ题目分类
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. (5)构造法.(poj3295) (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法: 转载 2015-06-04 08:45:36 · 372 阅读 · 0 评论 -
poj3349(数的哈希)
处理方式有好多种,算和,平方和,与,或之类的,我自己算的是个简单的,算和。主要是处理冲突,然后判断是否会出现相同的,可以顺时针,也可能是逆时针的。 但是自己过的很耗时,估计应该是开辟空间之类的造成的,还得好好研究一下。 #include "stdio.h"#include "string.h"#include "math.h"#include #include #inclu原创 2015-06-03 16:51:20 · 391 阅读 · 0 评论 -
hdu5273(区间逆序对的个数)
题目的大致意思是有一个数组,然后有Q个询问,对于每次询问给出L和R,然后要给出每次L和R区间内的逆序对个数。 解答方法就是先算出ans[0][1...N-1]的结果,然后根据再来算ans[i][i+1...N-1](0#include "stdio.h"#include "string.h"#include "math.h"#include #include #include #原创 2015-06-24 09:35:12 · 2695 阅读 · 0 评论 -
poj2299(求逆序对,归并排序)
归并排序求逆序对了,只要是逆序对的,肯定就会有交换的操作了,然后归并排序的时候,此时新数组放右边的数字时,计算逆序对个数(就是还未放入的个数),然后就可以得到答案了。 #include "stdio.h"#include "string.h"#include "math.h"#include #include #include #include #include #inclu原创 2015-06-03 11:19:31 · 402 阅读 · 0 评论 -
HihoCoder(79 -80weeks)
第79周题目描述:就是一个超级计算机有N个单元,每个单元有两种状态,开和关。然而对某些单元,当他们在相同的状态下时,会对机器造成不稳定。现在告诉你会造成不稳定的情况,问该计算是否存在一个稳定的状态,是的话输出“YES”,否则输出“NO”。解答:题意比较清晰,是个纯裸的二分图,对于i,j不能同时为状态st进行处理,然后可以得到一条语句就是i为1-st,或者j为1-st,然后就可以解决原创 2016-01-13 15:26:59 · 252 阅读 · 0 评论