poj
文章平均质量分 69
northsnow_bupt
这个作者很懒,什么都没留下…
展开
-
poj2023 DFS
/** * poj2023 DFS * 就是以前小时候常玩的那种做选择题然后翻页的那货,把每一页的内容都记下来以后用DFS的方法往下走就行了. * 第一个稍微麻烦的地方是输入,想办法把引号过掉,我这就用了最最原始的办法 * 第二个是可能会有循环的,或者貌似有多个解的,因此有正确答案以后要把正确答案的exist也设成true,这样只打印一次就行了,因为这个WA了3次 */#include原创 2014-03-18 00:23:16 · 332 阅读 · 0 评论 -
poj2352 树状数组
/** * poj2352 树状数组 * 就是树状数组啦 */#include #include int n;int level[15002];int tree[32003];//set according to xint lowbit(int x){ return x&(-x);}void update(int x){ while(x<=32002){原创 2014-03-18 00:35:55 · 299 阅读 · 0 评论 -
poj2299 归并排序求逆序数
/* * poj2299 逆序数 * 逆序数就是你如果只能交换临近的两个数,那么将一个序列变为有序序列所需要的最少交换次数 * 稳定的排序算法按理来说都可以求,但通常使用归并排序可以求逆序数,因为它的时间效率还是很高的,之所以逊于快排,还是因为它对空间的占用稍多,而且用到了迭代吧 * 提到逆序数我都第一个想到归并。思路很简单,从上往下,把序列不断二分,到长度为1时就一定有序了,再从原创 2014-03-18 00:35:00 · 376 阅读 · 0 评论 -
poj2236 并查集
/** * poj2236 并查集 */#include #include const int MAX_NUM = 1002;int n,d,d2;struct node_t{ int father; int x; int y;//position bool repaired;} nod[MAX_NUM];int getfather(int原创 2014-03-18 00:29:52 · 345 阅读 · 0 评论 -
poj2182 线段树/线段数组+二分搜索
/** * poj2182 线段树 * 我在这里先做了一个n^2的算法,就是比较直观的,从后往前 * 最开始是最后一个数,比它小的数有k个,那最后一个数就是k+1 * 那推广,第i个数,它前面比它小的个数为kk,再加上之前后面已经出现的比它小的个数pp加起来,再加1,那这个第i个数就是kk+pp+1 * 最后剩下一个数就是第一个数 * * * 再学习一下别人的线段树的方法 * 线原创 2014-03-18 00:28:38 · 577 阅读 · 0 评论 -
poj2157 BFS
/** * poj2157 BFS * 这个题,我只能说是非常的烦,烦爆了,但也没有什么办法。因为BFS是肯定的,但是细节的东西真的很难把握,不知道哪里错就WA了 * 我第一次自己做的,WA了无数次,后来还是放弃了,转用别人的思路重做了一遍,终于才AC * 这个思路就是遇到不能打开的门,先把这些门的坐标记下来,等你搜了一遍以后,以这些门的坐标作为起点,重新刷一遍bfs,因为之前已经刷过的点原创 2014-03-18 00:26:56 · 368 阅读 · 0 评论 -
poj2001 字典树
/** * poj2001 字典树trie * 知道是使用字典树就可以了,要注意树的树根是一个二级指针,因此结构体内也要使用指针数组 * 在字典树的结构体内,既维护树形的结构,也使用一个变量标记以当前(从上往下)为前缀的单词的个数 * 在最后检验时,自上而下查询一个词,并输出当前的前缀,直到向下的统计量为1,停止输出即可 */#include #include #include原创 2014-03-18 00:20:55 · 351 阅读 · 0 评论 -
poj1990 树状数组+排序
/** * poj1990 树状数组+排序 * 这个是个稍稍复杂的题目,涉及到了树状数组的使用.如果直接一个一个成对做判断的话,复杂度在n*(n-1)/2量级上,肯定完不成 * 我们先把所有牛的叫声v按升序排列,那么如果从最左边往右计算到当前牛i,v就是用c[i].v就可以了 * 再看x,我们将牛i左边的牛分成位置(x)在牛i之前和之后两种,分别计算 * 如果我们知道位置上在牛i之前的牛原创 2014-03-18 00:20:21 · 469 阅读 · 0 评论 -
poj1953 简单DP
#include using namespace std;/** * 比较简单的DP * dp[i][0] = dp[i-1][0] + dp[i-1][1];dp[i][1] = dp[i-1][0] * 分别表示长度为i,最后一个是0和1的长度 */int main(){ int n,scenario; const int MAXLEN = 46原创 2014-03-18 00:18:24 · 369 阅读 · 0 评论 -
poj1830 高斯消元法
/** * poj1830 高斯消元法(线性代数,矩阵求秩) * 就是一个解二进制的线性方程组,求解的个数,如果增广阵和系数阵的秩不等,那就无解,否则解的个数是2^(n-秩) * 求秩的过程就是逐行消去的过程,最左列为1的行下面,该列都消去为0,最后统计非全0的行就是秩了 * 这个题一上来先把xy搞混了,结果WA了好多次都没搞清楚错在哪儿 后来索性试了一下,才解决了问题 */#inc原创 2014-03-12 08:27:07 · 471 阅读 · 0 评论 -
poj2395 Kruskal最小生成树
/** * poj2395 最小生成树 Kruskal算法(加边法) * 就是个最小生成树,只是记录的是最大边的边长而已。环路检测可以用并查集。并查集好多次忘了要用父点做为操作点了,WA了好多次 */#include #include using namespace std;struct road{ int a; int b; int dist;}r[10原创 2014-03-18 00:37:12 · 386 阅读 · 0 评论 -
poj2426 BFS
/** * poj2426 BFS * 好像是一道AC率很低的题,非常繁琐,需要考虑的东西比较多,要认真一点做.我是看了别人的做的 * 对于+ - *三种操作,对K取模以后的结果都不耽误最后的计算; * 而对于%,由于之前的性质,多次取模结果是一样的,因此%只会出现一次,那么就只有两种情况会出现 * 第一种就是第一个操作符就是%,第二种是第一个操作符是*,%是第二个,这种情况下就产生了0原创 2014-03-18 00:38:33 · 555 阅读 · 0 评论 -
poj2002 排序+哈希
/** * poj 2002 排序+哈希 * 首先要有一个正确的大方向,就是取两个点,利用公式给出另外两个点,并搜索这另外的两个点是否存在 * 大方向有了,首先是确定另外两个点的方法,随意取点,可能组出多个正方形,判断的时候会取多次,这就浪费了很多运算量 * 吸取了别人代码的经验,首先将点先x后y升序排列,然后对于i=yj的点。有所改进的是,我们这里不需要对xi==xj的情况多做判断,这是原创 2014-03-18 00:22:47 · 362 阅读 · 0 评论 -
poj3259 Bellman_Ford
/** * poj3259 Bellman-Ford * 这个题最开始的时候有点钻牛角尖了,只记得Bellman_Ford是单源,而这个题并没有指定源是哪个,就用了Floyd,结果不对 * 想了下,Floyd好像并没有负向环路判断的功能,而这个题只是要检测负向环路,起点在哪里根本就无所谓,选一个根本都不存在的起点都可以 * 于是果断改用BF了 */#include int f;i原创 2014-03-18 00:39:18 · 327 阅读 · 0 评论 -
poj2227 最小堆+BFS
/** * poj2227 最小堆+BFS * 很有意思的一道题,思路是,维护一个以高度为标准的最小堆,先把边界的所有点加入堆,然后每次取堆顶,进行bfs * 检查四个方向的点,如果还没有加入堆的,将其加入堆 * 如果新加入的点高度小于堆顶高度(水盘边的最低高度),那么将堆顶高度-新加点的高度作为新加点的水面记入总和,并将该点的高度改为堆顶高度 * 直到所有点都被遍历为止。这个思路就是从原创 2014-03-18 00:29:17 · 457 阅读 · 0 评论 -
poj2038 模拟+next_permutation
/** * poj2038 模拟 next_permutation * 这个题感觉比较简单,用next_permutation就可以根据题面意思轻松完成任务了 * 先输入所有要比较的序列,然后用next_permutation一个一个计算120个序列和输入序列的差值 * 计算差值的方法也很土,字符的先后顺序一共只有4+3+2+1=10种,将两个输入序列的两字母间顺序都求出来,然后计算两个序原创 2014-03-18 00:24:25 · 331 阅读 · 0 评论 -
poj1974 排序 模拟
/** * poj1974 排序+模拟 * 一块空地上摆了若干石头,有石头的地上虫子不能躺,虫子在这块地上可以横躺可以竖躺,且只要躺就会伸到最长,但长度最少为2,问有多少种不同的躺法 * 直观的做法,分别考虑虫子横躺和竖躺两种情况,每种情况之前先将石头按相应的需要排序 * 先考虑横躺的情况,可用的位置有四种可能: * 1、连续两个石头之间有的空行,且列数>=2(后一个条件不容易想到)原创 2014-03-18 00:19:10 · 472 阅读 · 0 评论 -
poj2418 二叉排序树
/** * poj2418 二叉排序树 * 这道题目可以用二叉排序树来做,也可以用map来做,为了学习,这里我就用了二叉排序树的做法 * 点1:在读取字符串的时候,可以使用下面使用的正则方法,%开启正则,[]指定读取数据的格式,^\n指读取\n之前的数据,即一行,30是指读取的最大长度 * 而另一种方法则是使用gets(tree_name)函数,直接读取一行,更为简洁 * 点2:二叉排序原创 2014-03-18 00:37:52 · 998 阅读 · 0 评论 -
poj2379 排序
/** * poj2379 排序 * 这个题算是一个比较简单的排序,但是题目的意思比较模糊,需要重新总结一下才比较清楚 * 我最开始对于ti的理解是有误的,我以为ti是一次题目运行的时间,实际上不是,ti是本次提交的时间,是它反映着多次记录之间的顺序 * 主要的纠结点在于时间的统计,题目的真实意思是,一道题目如果没能AC,则不计入时间统计,如果AC了,这道题的时间为,第一次AC所用的时间+原创 2014-03-18 00:36:23 · 383 阅读 · 0 评论 -
poj2051 优先队列(自实现版本和STL版本)
/** * poj2051 优先队列_最小堆的自实现与STL的priority_queue * 最小堆的实现: * 插入操作:进来一个值放在队尾,然后从下往上比较,直到满足堆的要求 * 删除操作:将堆顶和堆底的一个值互换,然后从上往下比较,直到满足堆的要求(因为之前,堆的左右子树都是堆),最后去掉新对底的值 */#include #include using nam原创 2014-03-18 00:25:47 · 412 阅读 · 0 评论 -
poj1860 Bellman-Ford
/** * poj1860 Bellman_Ford * 是一个逆向使用bellman_ford算法的题目。原来单源最短路径的算法是避免负的环路,这里我们反过来,是求正的环路 * BF算法的核心思想就是,单源最短路径如果存在,即不存在环路,那么在N个点的图中,我N-1次松弛一定可以存在最短路径.否则负向环路就会出现 * 用在这里就是,N个点的图中,N-1次松弛一定可以找到潜在的正向环路原创 2014-03-18 00:41:20 · 361 阅读 · 0 评论 -
poj1732 DP
/** * poj1732 背包问题 * 乍一看还以为是DFS题,照着DFS做了一遍发现超时了 * 仔细一分析,哦,dfs是指数级的复杂度,怎么可能不超时呢,还是按DP的方法来做吧 * */#include #include const int MAX_NUM = 100001;int min(const int a, const int b){ return a>b原创 2014-03-12 08:23:27 · 373 阅读 · 0 评论 -
poj1727 排序+二分搜索
/** * poj1727 排序+二分 * 类似题目的附图,在每个点以正负1为斜率作直线,两条直线以下的点就可以作为它的因果点 * 最大值就是所有点中最小的纵坐标;最小值,是最左的-1斜率直线与最右的+1斜率直线的交点 * 对符合范围的t进行二分定位,每一级t计算能覆盖所有输入点的最小点数count,如果count > m则向上查找,反之向下查找。最后输出的就是满足count <= m的最原创 2014-03-12 08:19:44 · 495 阅读 · 0 评论 -
poj1723 排序+中位数
/** * poj1723 * 排序+中位数 * 目的纵坐标很容易想到是中位数,其实横坐标也一样 * 如果目的x坐标是a,a+1,a+2,那么移动步数应该是sum(|x[i] - a - i|) * 那么a是x[i] - i的中位数就可以了 * 不用担心步数重复的问题;合理安排顺序一定可以保证步数够用,所有绕远都可以通过改变顺序的方法解决 */#include #i原创 2014-03-12 08:18:25 · 360 阅读 · 0 评论 -
poj1664 DFS
/** * poj1664 DFS */#include int count;char path[11];void dfs(int left,int num,int len){ if(num == len){ if(left == 0){ ++count; } return; } in原创 2014-03-12 00:24:27 · 359 阅读 · 0 评论 -
poj1176 枚举
/** * poj1176 枚举 * 我想这个题的本意应该是DFS,但因题义有限制,所以一共就8种情况,枚举就行了,实在不必费力DFS * 首先,我们只看前6个灯的状态就可以了,剩下的都是以6为模重复的 * 然后,4个操作都是2元的,也就是说只有奇数次和偶数次操作,而且连续两次相同操作之后,结果是一样的 * 4个2元操作最多有16种结果,但实际上,可能出现的6灯状态只有8种,我们只要按需原创 2014-03-12 00:11:23 · 563 阅读 · 0 评论 -
poj1128 拓扑排序+DFS
/** * poj1128 拓扑排序+深度遍历 * 这个题的思路还是比较有意思的,方块叠在方块上,让你找出来叠加的顺序。每个方块的四条边都肯定有没覆盖的点,这就很好确定每个方块的位置 * 第一个关键点是,对于一个字母,你看谁在你的方块上,就能确定谁的叠加顺序就高于你,这就形成了一个有向图,利用拓扑排序就可以完成排序的操作 * 这里简单叙述一下拓扑排序吧,就是给你一个有向图,将所有的点按照原创 2014-03-12 00:08:39 · 452 阅读 · 0 评论 -
poj1731 next_permutation
/** * poj1731 字典序(next_permutation) * 其实用DFS也可以,一样用一维的标志位数组就可以标识字母是否出现过了, * 在一级深度遍历完并恢复了v[i]=false之后,while(s[i] == s[i+1]) i++,把连续的相同字母都跳过就可以了, * 而之前第一个字母DFS过的,就已经包含了需要的序列 * 当然,我这里用的next_permutat原创 2014-03-12 08:20:35 · 328 阅读 · 0 评论 -
poj1231 模拟?简单几何?
/** * poj1231 简单几何 * 这题也根本不是什么搜索题 * 先把所有字母的方块的四个边的值求出来 * 然后为了划分各个字母独立的区块,将原有的方块进行扩充 * 比如 * B * B D * D * 就需要将原有的B方框向下扩充到D,将原有的D方框向上扩充到B * 合并的规则就是 * if(left[i]原创 2014-03-12 00:16:38 · 432 阅读 · 0 评论 -
poj1166 枚举/BFS
/** * poj1166 枚举/搜索 * BFS来枚举可能出现的情况,是一个比较一般的思路 * 我这里就没有用BFS,而是用线性代数的方法减小搜索范围,然后用了枚举 * 但是要想证明解的必存在性,以及进行减小搜索范围,就需要用一点线性代数的思想了 * 每个表只有4中不同的状态,每个表都只有固定的几种操作可以改变其状态,而4个状态有是一个循环,是不是能联想到"线性相关"和"线性无关"的概原创 2014-03-12 00:09:58 · 550 阅读 · 0 评论 -
一个数字题
最近实验室工作很烦,而且额外又接了点写网站的工作,一直在学web编程,没来得及写poj了。不过今天从网上看到了一个挺好玩的题,突然来了兴趣想做做。题目很简单 求最小的正整数M,使得任意比M大的整数N都有N=140*a+9*b+6*c,其中a b c都是自然数先设定了一个范围,用穷举的方式得到了问题的解。但从分析的角度来说,穷举肯定是不行了,需要一种特别的思路。那么就想到了以原创 2013-10-12 19:39:04 · 455 阅读 · 0 评论 -
POJ2965的枚举解法和高效解法
DescriptionThe game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator.There are 16 handles on the refrigerator door. Every handle can b原创 2013-09-05 21:55:49 · 2471 阅读 · 0 评论 -
poj1745 0-1DP
/** * poj1745 0-1DP * * 用dp[ i ][ j ] 表示加上或减去第 i 个数后,所得值取模后的值能否为 j ,所以dp为bool型即可。 * 状态转移方程:dp[ i ][( j + num[i]) % k] = true; dp[ i ][( j - num[i]) % k] = true; (当然,必须满足dp[ i - 1 ][ j原创 2014-03-12 08:25:23 · 458 阅读 · 0 评论 -
poj1915 BFS
/** * poj1915 BFS * 乍一看以为是DP,想了半天也没有想出一个特别好的dp方案来,果然还是走BFS吧 * 做法比较简单粗暴了,代码也很粗暴,就是宽搜,从最初始点开始,8种方向只要能走就走一步,只要这个点还没有走过,就将其作为新的出现的点记录下来 * 依照步数从小往大升序地遍历,得到的一定是最小值 */#include #include const int MAX原创 2014-03-12 08:27:39 · 388 阅读 · 0 评论 -
poj1321 DFS
/** * poj1321 DFS * 这个题自己当时并没有直接想出来,而是参考的网上别人的思路 其实能想到是DFS,但是思路里DFS的特别设计是我没有想到的 * 首先,这个dfs使用了行和棋子数两个参数,而不像之前字符串排序那样只需要一个参数 * 行作为参数就可以确定哪些行已经被搜索,哪些行尚未被搜索,那么只需要标记哪些列被搜索过就可以了 * 第二,由于存在k<n的情况,这就意味着可能原创 2014-03-12 00:19:23 · 358 阅读 · 0 评论 -
poj1182 带权并查集
/** * poj1182 带权并查集 * 运用并查集进行分类、合并的操作,最开始大家都是自己为一个集合,随着小集合逐渐结成,小集合向另一个集合合并时,就可以将吃和被吃的关系统一起来,找到统一的参照系 * 这就是带权并查集存在的意义 * 在unionset函数中,负责合并的时候,将被合并一个集合的根的类型进行相应翻转,而在getfather函数中,自上而下对该树枝进行了修正 */#in原创 2014-03-12 00:13:43 · 392 阅读 · 0 评论 -
poj1950 DFS
/** * poj1950 DFS * 很直接的dfs我也试过,就是生成一个符号序列,然后从左到右算一遍 这个没有问题,但是速度比较慢,8XXms * 那我就考虑事先保存前面的结果,减少计算量,但是这个题有个类似于计算器的东西,从左往右走的话,会有优先级的问题,那DFS的时候也得小心这个 * 所以我的dfs函数就有四个参数,阶数、左操作数、右操作数和操作类型 * 初始化的时候,左操作数为原创 2014-03-12 08:29:21 · 487 阅读 · 0 评论 -
poj1007 稳定排序 归并排序
/** * poj1007 稳定排序 归并排序 * 正好在这里重新复习一下归并排序 * 归并排序的思想是,把一个序列二分拆成前半段和后半段,递归深入的方法,使得前后的两个半段序列都是有序的(mergesort函数) * 然后将两个序列合并成一个有序的序列(merge函数) * 合并时,先给前后两个序列都做一个副本,然后向原来两个序列的空间内依次填充两个子序列中更小的一个 *原创 2014-03-12 00:03:15 · 588 阅读 · 0 评论 -
poj1656 二维树状数组
/** * poj1656 二维树状数组 * 二维线段树的做法太繁琐了,暂时先不看了,二维树状数组的做法相对简单些,但题目中这样的实现,确实减轻了查询的复杂度,但是插入的复杂度却确实提升了比较多 * 思路大概就是在一维的树状数组的插入和查询操作循环内部嵌套一个另一维的操作就可以了 * 听说这个题暴力也能过,所以看样子并不会对复杂度控制太高吧 */#include #include原创 2014-03-12 00:23:06 · 544 阅读 · 0 评论 -
poj1606 BFS
/** * poj1606 BFS * 这个题看到的两种主流的方法,一个是BFS,另一个是根据状态去按序输出,类似于模拟 * 模拟的方法应该速度会更快,但是需要有足够的证明才好,正好我还没有怎么练过BFS,就先按BFS的方法做吧 * 用BFS竟然给了0ms,看来测试用例还是比较简单的 * BFS的思路和DFS不太一样,DFS的实现是递归,而BFS的实现是循环,并建立新的节点 * 这道题原创 2014-03-12 00:21:27 · 508 阅读 · 0 评论