摘要: 这道题我是看了别人的题解才做出来的。题意和题解分析见原文http://blog.csdn.net/lyy289065406/article/details/6698787这里写一下自己对题目的理解。1. 根据k的最大范围直接搜索n最后5位的方法是错误的,因为它并不能保证所求结果为最小。因为题目要求最后结果m要尽量小,而改变n的高位能够得到更小的值。k m尽量小。即最终得到的结果不一定是最小的,但一定是与n对应位置数字不相等个数最少的。这也决定了本题dfs的写法。3. 面对大量大数取模运算,利用mod[i][j]预处理(10^i)*j模k的值,节省了大量时间。这样在dfs的过程中,改变某一位后的 阅读全文
posted @ 2013-08-10 15:13 fenshen371 阅读(576) 评论(0) 推荐(0) 编辑
摘要: 题意:由n个牧场,编号1到n。每个牧场有一头牛。现在在牧场x举办party,每头牛都去参加,然后再回到自己的牧场。牧场之间会有一些单向的路。每头牛都会让自己往返的路程最短。问所有牛当中最长的往返路程是多少。思路:n最多到1000,floyd肯定超时。可以这样做,把图中所有的边先存起来,然后第一次用dijkstra求出以x为源点到每个点的最短距离。该最短距离为每头牛回家时的最短距离。然后建个新的图,将之前存的边反向加入图中。如之前有条从5到8距离为2的路,则此时向图中添加的边为从8到5距离为2的边。这样再次以x为源点求到每个点的最短距离,将两者相加,就是每头牛往返的最短距离了。求其中的最大值即可 阅读全文
posted @ 2013-08-07 18:01 fenshen371 阅读(274) 评论(0) 推荐(0) 编辑
摘要: 题意:有a个村庄,编号为1到a,有b个城堡,编号为a+1到a+b。现在超级玛丽在a+b处,他的家在1处。每条路是双向的,两端地点的编号以及路的长度都已给出。路的长度和通过所需时间相等。他有一双鞋子,可以使用k次,每次使用后最多可以跑过l的距离,且通过这段距离所需时间为0。使用鞋子时,必须从村庄或城堡开始,到村庄或者城堡结束。但是,城堡充满了陷阱,他如果中途遇见城堡,就必须停下来,且鞋子视为使用完了一次。问超级玛丽回家所需的最短时间。思路:用floyd算法先处理出任意两点间的最短距离(不用鞋子时)。另用一个二维数组来维护两点之间是否允许用鞋子直接传送。当两点最短距离不大于l且中间不经过城堡时,数 阅读全文
posted @ 2013-08-07 17:42 fenshen371 阅读(246) 评论(0) 推荐(0) 编辑
摘要: 题意:给一个字符串,求该串最多由多少个相同的子串相接而成。思路:只要做过poj 1961之后,这道题就很简单了。poj 1961 详细题解传送门。假设字符串的长度为len,如果 len % (len - next[len])不为0,说明该字符串不能由其他更短的字符串反复相接而成,结果输出1,否则答案为len / (len - next[len])。 1 #include 2 #include 3 #define maxn 1000010 4 char s[maxn]; 5 int next[maxn]; 6 void get_next(char str[]) 7 { 8 next[0]... 阅读全文
posted @ 2013-08-07 11:41 fenshen371 阅读(178) 评论(0) 推荐(0) 编辑
摘要: 题意:给一个长度为n的字符串,如果它长度为l(2 2 #define maxn 1000010 3 char str[maxn]; 4 int next[maxn], len; 5 void get_next() 6 { 7 next[0] = -1; 8 int i = 0; 9 int j = -1;10 while (i < len)11 {12 if (j == -1 || str[i] == str[j])13 {14 i++; j++;15 next[i] = ... 阅读全文
posted @ 2013-08-06 20:21 fenshen371 阅读(221) 评论(0) 推荐(0) 编辑
摘要: 题意:有n只虫子,每次给出一对互为异性的虫子的编号,输出是否存在冲突。思路:用并查集,每次输入一对虫子后就先判定一下。如果两者父亲相同,则说明关系已确定,再看性别是否相同,如果相同则有冲突。否则就将两只虫子并入一个集合。而性别则是用一个gender数组来维护,每个虫子的gender的值为0或者1。0表示该虫子的性别与父亲结点的性别相同。1表示该虫子的性别与父亲结点的性别不同。这题和poj1703本质上是一样的。1703的题解请点传送门。另外还有一个疑惑,本题输入量巨大,我用输入加速后反而比用scanf要慢得多,弄不明白为什么。。有知道的大神欢迎来给解答一下。 1 #include 2 #def 阅读全文
posted @ 2013-08-03 18:46 fenshen371 阅读(187) 评论(0) 推荐(0) 编辑
摘要: 题意:城市中有两个帮派,输入中有情报和询问。情报会告知哪两个人是对立帮派中的人。询问会问具体某两个人的关系。思路:并查集的应用。首先,将每一个情报中的两人加入并查集,在询问时先判断一下两人是否在一个集合中,如果是,则表明两个人的关系已知。本题还需要判断出两人是不是在同一帮派,这里用一个relation数组来维护每个人与根结点的关系。0表示该人与根节点为同一个帮派。1表示该人与根节点为对立帮派。并查集有两个基本操作:find——查找根节点, merge——合并两个集合。在合并两个集合时,其中一个集合的relation的值要发生变化。在这里只需要改变集合根节点的relation(改变的规则见代码中 阅读全文
posted @ 2013-08-03 11:18 fenshen371 阅读(203) 评论(0) 推荐(0) 编辑
摘要: 题意:一棵苹果树有n个结点,编号从1到n,根结点永远是1。该树有n-1条树枝,每条树枝连接两个结点。已知苹果只会结在树的结点处,而且每个结点最多只能结1个苹果。初始时每个结点处都有1个苹果。树的主人接下来会进行m个操作。操作共两种。C X表示将结点x上的苹果数量改变,原本是1,则现在为0,原本是0,现在是1。Q X表示一次查询。要求输出结点X和其子树上的苹果总数。n和m最大可到100000。操作只有更新和查询两种,树状数组最合适了。首先是树状数组的相关知识。网上有很多讲解,在这里传送一个讲解的地址传送门树状数组最重要的就是要搞明白那种经典的图,之后就没什么问题了。思路:本题的关键是如何将树映射 阅读全文
posted @ 2013-07-30 19:35 fenshen371 阅读(289) 评论(0) 推荐(0) 编辑
摘要: 题意:给出n个数的非递减序列,进行q次查询。每次查询给出两个数a,b,求出第a个数到第b个数之间数字的最大频数。如序列:-1 -1 1 1 1 1 2 2 3第2个数到第5个数之间出现次数最多的是数字1,它的频数3。思路:假设查询时的参数为a, b。这道题查询时有以下两种情况:1、 num[a] = num[b]. 即区间内的数字全相同,此时答案为b - a + 1。2、 如果不相同,则以一般情况来讨论。见下图。因为序列为非递减序列,因此值相同的数字必然连续出现。将区间分为3部分。num[a]以及与它值相同的区域构成第一部分,num[b]以及与它值相同的区域构成第三部分。区间[a, b]中剩下 阅读全文
posted @ 2013-07-29 15:30 fenshen371 阅读(477) 评论(1) 推荐(1) 编辑
摘要: 题意:有n头牛,编号从1到n,每头牛的身高已知。现有q次询问,每次询问给出a,b两个数。要求给出编号在a与b之间牛身高的最大值与最小值之差。思路:标准的RMQ问题。RMQ问题是求给定区间内的最值问题。当询问量巨大时,最朴素算法必然超时。解决RMQ比较优秀的算法有ST算法。其预处理时间复杂度为O(nlogn),询问的时间复杂度为O(1)。ST的思想如下:假设num数组中的数据从第0位开始存储。用两个二维数组tmax,tmin分别求区间最大与最小值。ST的关键是数组区间的分割。tmax和tmin的下标是一致的,暂且拿tmax举例。预处理:预处理阶段运用的是DP的思想。tmax[i][j]内的值为区 阅读全文
posted @ 2013-07-29 11:11 fenshen371 阅读(237) 评论(0) 推荐(0) 编辑