摘要: 这是一道差分约束系统的题目。所给的约束条件是对于一个序列的子序列来说,子序列的和大于或小于一个数,问是否存在一个序列,使得所有约束条件全部成立。 我采用用数列中类似于数列求和的方式,比如序列a1,a2,a3....令s1=a1,s2=a1+a2,s3=a1+a2+a3...为了方便,我还引入了s0=0,这样就可以根据题目的条件列出不等式,再把不等式转化为求最短路的问题。开始我想当然地认为si>=si-1(i和i-1为下标),加了这个条件之后当然是错的,后来发现了这个问题,将其去掉,但是却忽略了一点:这道题其实是让我判断是否存在负环。因为图可能不连通,所以应该每个点都要作为一次起点,用SP 阅读全文
posted @ 2012-08-17 19:36 等待电子的砹 阅读(437) 评论(0) 推荐(0) 编辑
摘要: 这是一道差分约束系统的题,刚开始学,还有些地方不是很清楚,靠这道题弄清了一些问题。这道题是是说有一队奶牛要吃饭,有些奶牛互相讨厌,必须至少相隔一定的距离;有些奶牛互相吸引,距离不能大于一个定值。另外,这些奶牛可以处在同一个位置。求这队奶牛最远的长度。 拿题目的数据来说(1,3,10)、(2,4,20)、(2,3,3),很容易得出不等式:x3-x1<=10;x4-x2<=20;x3-x2>=3。并且,由于奶牛顺序不能改变,所以Xi>=Xi-1(i-1是下标)。我们可以把不等式变形为:x2<=x1+5;x3<=x1+10;x2<=x3-20。从而转化为求最 阅读全文
posted @ 2012-08-16 16:27 等待电子的砹 阅读(386) 评论(0) 推荐(0) 编辑
摘要: 这是一道简单的KMP求next数组的题,几乎不用动脑筋,可以用来练练手,直接把两个字符串连接在一起求next就行了,唯一要注意的就是长度不能大于原来任一字符串的长度,如果长度大于了,要选择len1和len2中较小的一个输出。#include<stdio.h>#include<string.h>#define MAX_STR 50005char str1[MAX_STR*2],str2[MAX_STR]; int next[MAX_STR*2];void get_next(int,int);int main(){ char oupt[MAX_STR]; while(sca 阅读全文
posted @ 2012-08-13 21:05 等待电子的砹 阅读(516) 评论(0) 推荐(0) 编辑
摘要: 这道题是考察对next数组性质的应用。题意相当于是求一个长字符串中循环节的个数。 由于我们知道next数组中存的是一个位置(假设next[j]的值为k,对应的字符串为M,如果k>0,那么M[0....k-1]和M[j-k.....j-1]是相同的,并且0...k-1这个序列一定是最长的),比如a b c a b c d(next值:-1 0 0 0 1 2 3 ),由next[6]=3可知,M[0..2]=M[3..6],这就找到了循环节,于是我们思考从next数组作为切入点,来找到一种方法来求得循环节的个数。 看看next数组的一个性质:next始终是从-1开始增加(在变为0之前)。. 阅读全文
posted @ 2012-08-13 10:56 等待电子的砹 阅读(695) 评论(0) 推荐(0) 编辑
摘要: 一道KMP算法的基础题,用于熟悉KMP算法和求next数组,关于KMP算法,为自己写了一篇总结。 这道题要注意的是,模式串可以重叠,比如给出ACA与ACACACA,应该出现了3次,这里只需要在KMP的函数里稍微改动一下即可:如果模式串的位置等于了模式串的长度,说明模式串已经被完整地匹配了,并且,此时模式串的位置由于等于了长度,所以这里是并没有字符的,但next值会存在(详情见求next数组的值的函数),此时只需要假设它们不匹配,转到此时的next值即可。#include<stdio.h>#include<string.h>#define MAX_WORD 10005#d 阅读全文
posted @ 2012-08-11 17:01 等待电子的砹 阅读(134) 评论(0) 推荐(0) 编辑
摘要: KMP算法开始学的时候很不好理解,自己写了篇总结一下放在这里,使自己的思路清晰一下。 KMP算法之所以能够以o(m+n)(m为模式串长度,n为匹配串长度)的复杂度完成字符串匹配,是因为KMP算法不同于朴素的算法要进行匹配串指针的回溯。举个例子,对朴素的算法,如果要在”aadadefgadk“中匹配"adk“,首先比较"aad"与"adk",发现不匹配,然后再比较"ada"与"adk",考虑一种极端情况"aaaaaaaac"(有8个a)与"aaaaaaac"(有7个a 阅读全文
posted @ 2012-08-11 16:45 等待电子的砹 阅读(1453) 评论(0) 推荐(2) 编辑
摘要: 这是一道二维的树状数组。与一维不同之处在于更新和求和都多了一重循环:更新:void update(int a,int b,int val){ int i,j; for(i=b;i<=lmt;i+=lowbit(i)) { for(j=a;j<=lmt;j+=lowbit(j)) { c[i][j]+=val; } }}求和:int get_sum(int a,int b){ int i,j,sum=0; for(i=b;i>0;i-=lowbit(i)) { for(j=... 阅读全文
posted @ 2012-08-10 10:16 等待电子的砹 阅读(144) 评论(0) 推荐(0) 编辑
摘要: 一道树状数组的应用题,和POJ 3067非常类似,这道题是求比自己强壮(e更大,s更小)的牛的数量。 将POJ 3067的思路应用到这道题上,如果先对e按照降序排列,每加入一只牛,当前已经加入树状数组的牛的s如果比这只牛小,那么那些牛就更强壮,所以同样是在树状数组里的求和问题。同样,对s的排序规则关系到e相同时的情况,由于s更小就更强壮,所以先把s小的加入,于是s就按照升序排列。再考虑e和s都相同的情况,假设有一些牛的e和s都相同,为cow1,cow2.....,cowK,那么更强壮的牛的数量x,满足cow1=cow2=....=cowK=x。所以遇到e和s都相同的状况时,只需要复制答案... 阅读全文
posted @ 2012-08-09 14:59 等待电子的砹 阅读(422) 评论(0) 推荐(0) 编辑
摘要: 这是一道运用树状数组的题。大意是求直线的交点数,前提是交点只能有两条直线相交,不能出现三点交于一点的情况。需要注意的是就是排序的规则。 假设东海岸的城市坐标为x,西海岸的城市坐标为y,当有一条公路(x1,y1)时,再修一条公路(x2,y2)与(x1,y1)相交,显然,当(i)x2>x1且y2<y1或(ii)x2<x1且y2>y1时,两条公路才会有交点,由于此时x,y有两个变量,都在变化,不好思考,不妨将y按照降序排列。那么,当有一条公路(x1,y1)时,需要再修一条(x2,y2),由于此时y已经按照降序排列了,所以y2<=y1.当y2<y1时,如果此时x2& 阅读全文
posted @ 2012-08-09 14:38 等待电子的砹 阅读(212) 评论(0) 推荐(0) 编辑
摘要: 这是一道树状数组的基本操作题,熟悉树状数组的更新操作和求和操作。题意是求对一个坐标 (X,Y),求 (x,y)的个数,其中x<=X,y<=Y。由于坐标按照y的升序给出(如果y相同,又按x的升序给出),所以这里只用得着x一个坐标,每得到一组坐标(a,b),就求x坐标小于等于a的星星个数,再将坐标为a的星星个数更新(加1)。 另外,为防止x=0在lowbit()中造成死循环,每次得到x坐标都应该加1.#include<stdio.h>#include<string.h>#define MAX_STAR 32010 int n,c[MAX_STAR],level[ 阅读全文
posted @ 2012-08-08 17:23 等待电子的砹 阅读(162) 评论(0) 推荐(0) 编辑