随笔分类 - Ural(Timus)
摘要:图论构造类问题题意:输入n个点,要求你连接一些边,使其变为无向图,并且,在图中任选3个点,这3个点的度都不会完全相等构造方法是对于奇数个点,第n/2+1个点不要连线,将点集分为相等的两部分,1到n/2为一部分,n/2+2到n为一部分,从第一部分开始连线,都指向第二部分,1号点连n/2条,2号点连n/2-1条,3号点连n/2-2条………………n/2号点连1条对于偶数个点是一样的,刚好能将点分为两个部分,两个部分的连线方法一样(这构造太巧妙了,很容易就能看到不会有3个点的度相同)#include <iostream>#include <cstdio>#include <
阅读全文
摘要:几何题题意:给出n个圆的圆心坐标和半径,给出一个单位方格,在(0,0),(0,1),问这些圆覆盖的面积占方格的百分比,圆超出方格的部分不计算。另外算百分比,答案精确到1%即可,即整数部分正确即可,小数部分不要求这题,可以想按照题意直接下手,未免太难了,另外注意到答案的输出,其实对精度的要求很低(对小数都没要求)。我们可以用一直近似的算法来解决将方格分割为一个一个的小格子,当分割得很小的时候,格子可以看做是一个点,然后看这个点在不在圆上或圆内,在的话相当于圆覆盖了这个点,覆盖了这个格子。所以我们将1*1方格分割为1000*1000的格子,然后逐一去判断,很暴力的方法,但就是这样过了#includ
阅读全文
摘要:数据结构--二叉查找树遍历题意:n,表示二叉查找树的节点个数,每个节点有个数值,并且数值各异不会出现重复的,查找树左子树的节点数值小于根,右子树的节点数值大于根。 一般的后序遍历二叉树时 左孩子,右孩子,根 ; 现在定义一种新的后序遍历 右孩子,左孩子,根 输入n,下面一个序列,是普通后序遍历二叉树的序列 , 要你根据这个序列,输出新定义的那种后序遍历序列 讲到这里,看图,看sample可以理解题意了要是一般的二叉树只知道后序遍历序列是不能建树的,但是这里是二叉查找树却可以对于一个后序遍历序列,它可以分解为 (左子树部分)(右子树部分)(根),由于是查找树,可知(左子树)<(...
阅读全文
摘要:数据结构:暴力(可用哈希优化)+建树+前序遍历题意:输入行数n,下面n行是一下文件的路径(和平常使用的电脑一样),一整行数据中没有空格(还好,别有搞些空格出来),要你整理好所有文件的路径,从根开始,输出所有的文件夹名首先一点,我们要名字,在同一个文件夹下,是不会有重名的文件夹的即a\ba\b这种是非法的(和电脑一样),但是输入中可以有,有的话只是一种重复输入,不是代表a下面真的有两个b然后不同文件夹下可以由相同的名字,就好比你D盘和E盘都有一个文件夹叫“电影”例如a\bd\b这种是合法的在输入中也是会出现的,看case就知道。另外,每个文件夹都只有一个双亲好像a\b\c\d , 你要找d,输入
阅读全文
摘要:树DP题意:输入n和m,表示n个城市,m条无向边,下面一行n个数字,表示每个城市的权值,下面m行是每条边的信息,u,v,w,顶点和边权。问你从一个城市出发,走出一条路线,使得权值和最大,权值和包括这条路线上城市的权值和边的权值和。题中有一句话出卖了它是个树DP:It turned out that if Petrovich can fly (using one or several flights) from townito townj, then there is exactly one way to do this.从一个顶点去另一个顶点如果连通的话只有一条路径,说明这个无向图其实是个无根
阅读全文
摘要:树DP经典问题,公司聚会,下属和直属上司不能共存,给出每个人的快乐值,再给出每个人的编号和他的上司,选出一些人参加聚会使快乐值最大/*从叶子开始选择,每个节点只有选不和不选两种可能,dp[rt][0],dp[rt][1]分别表示选和不选该节点dp[rt][1]=sum{ dp[son][0] }+val[rt] , 因为跟选了它的儿子就全部不能选dp[rt][0]=sum{ max{dp[son][0] , dp[son][1]} }如果根不选,那么儿子的选择就多样化了,每个儿子又是互不干扰的所以令每个儿子最优,加起来根就是最优的,而每个孩子无非还是选和不选,一比较就能得到每个儿子的最优方案而
阅读全文
摘要:数据结构:堆题目请你写一个内存管理系统。 内存中有30000个块,编号为1..30000。 当操作系统需要内存时内存管理系统会找出编号最小的空闲块,向里面写入数据。 操作系统还会会发出指令读取某个编号的内存块。如果目标块空闲,读取失败,否则读取成功。 一开始所有块都是空闲块。被写入数据之后就不是空闲块了。 如果一个块在600秒内没有被写入或读取,这块内存自动清空,变为空闲块。 本题中不会出现内存块不够用的情况。输入格式每行一个要求,可能是申请内存或读取。申请内存的格式如下: T + T表示这条请求收到时的时间,是不大于65000的整数,以秒为单位。读取内存的格式如下: T . N T表示这条请
阅读全文
摘要:树型DP:二叉苹果树另外一个提交地址:http://www.cqoi.net:2012/JudgeOnline/problem.php?id=1375里面有中文题目,不解释题目了。树型DP:主要是两点,怎么建树,怎么DP。这两者应该说是相互制约相互影响的,怎么DP就要怎么建树,而建树方法对不对也决定了你能不能DP。所以先分析怎么DP的,再分析怎么建树题意说要保留m个树枝,而且注意权值不是点的而是树枝的,这样子并不利于我们解决问题,我们可以转化一下,把权值转移给节点。首先给出所有边的信息后,我们的建树是唯一的(这个问题值得思考一下为什么,唯一是指不考虑左右孩子的位置,而只考虑从属关系,好像1(3
阅读全文
摘要:线段树题意:很明显的线段树。做了这题更加让我注意了用点和用段来建树的区别。这题是用点来表示线段的。一开始从0到10^9这个点之间的线段都是白色的,然后m个更新,每个更新 a,b,col,表示从点a到点b这条线段染成黑色或白色,问最后,白色线段中最长的是哪一段,输出它的位置(即线段两端的端点)注意更新的时候a,b的数值范围是 0<a<b<10^9 , 其实这样给数据方便了处理,否则的话最后要搞一下挺烦的先看看用段和用点表示线段树的区别。用点的话,0,1,表示的长度是1。1,3表示的长度是2。而用段的话1,3表示的长度是3,就是这个意思线段树的建树,无论在何种情况下,应该说建树的
阅读全文
摘要:并查集题意:题意比较好懂简单说一下。一个序列,只有0,1;输入n,表示序列长度(从1到n标号),输入m,下面m个更新,每行都是a,b,string,表示说序列中下标a到下标b的元素中有偶数个或奇数个1.没得到一个更新就更新序列的信息,知道读入第k个信息,和已建立的信息矛盾,那么结束,输出k-1,表示前面k-1个更新不矛盾,如果m个更新都成立,那么输出m这题要转化一下,一转化就比较明显了。我们定义前缀和为sum[i]表示1到i的和,那么sum[b]-sum[a-1]=c[a]+c[a+1]+c[a+2]……c[b] , 即序列的[a,b]区间和因为序列中只有0,1所以区间和的奇偶性就是该区间拥有
阅读全文
摘要:树状数组经典入门题,只要搜索数星星就能在各个OJ找到这个题目,不过不同OJ的输入和输出可能不同,但是题意是一样的,就是统计每个星星的等级入门题详细说一下。首先对输入的星星进行排序,先按x坐标升序排序,x坐标相同的按y坐标升序排序,这样做是后面能使用树状数组的根本保证。由于这题,输入数据中就已经保证了是按y坐标升序输入若y坐标相同则按x坐标升序输入,所以不需要排序,注意,两种排序方法是一样的。下面就按本题的来讲树状数组中是由原数组变化得到的,a是原数组,c是树状数组,并且数组是从下标1开始的,为什么从1开始是因为位运算和二进制的一些问题。在这里我们已经知道0<=x,y<=32000,
阅读全文
摘要:贪心 or 动态规划题目是归在动态规划里面的,但是看完之后觉得是贪心,而且貌似是水题,不知道为什么会把难度定为400多,觉得定为100多可以了题意:输入a,b,表示有b-a+1个数,然后给出这n个数,将他们划分成几块,每块都是单调递增的或者单调递减,问块数最少是多少贪心:首先处理一下原序列中相邻的数字不能相同,一开始没有做这个处理是WA的,处理后AC。所以题目的意思应该是指严格单调,相同的部分是不算在里面的(个人理解,否则没法解释这个WA)。好像1 2 3 3 3 3 4 是变为1 2 3 4
阅读全文
摘要:DP(DAG最长路)题意:给出x轴上的线段的端点坐标,一个线段能覆盖另一个线段(端点不能相同),求出最多的线段覆盖并且从短到长给出路径。转化模型为DAG,求DAG上的最长路并且打印路径,用记忆化搜索实现#include <cstdio>#include <cstring>#define N 550int a[N],b[N],n;bool g[N][N];int dp[N],path[N];void dfs(int i){ if(dp[i]!=-1) return ; dp[i]=1; for(int j=1; j<=n; j++) if(g[i][j]) { ..
阅读全文
摘要:DP(解码)题意:给出一个串的长度n,串只有0,1组成,但是不能有两个相邻的1。按字典序给串排列,最先肯定是0000,接着是0001,依此类推。给一个数字m,输出在长度为n的情况下,第m个排列的串是什么,如果m大于总排列数,输出-1这其实是一个解码的过程,必须用高位到低位解码(从左到右),因为这里要求字典序,字典序的比较水从左到右的由于数据规模固定在串长度44以内,所以我们先dp出所有长度下可能的排列数,编码时也要用每次编码按位编码,判断当前位为0还是为1,就是看填0或1可能产生多少排列数然后和m比较,这个看代码大概都能懂的#include <cstdio>#include <
阅读全文
摘要:DP+高精度+滚动数组还是1009的题目,不过数据再大点,数组都开不下,需要滚动数组。回想1009的递推的方式,可以看到,要知道当前位的信息,只需要知道前一位的信息即可,所以其实任何时候都只需要两位,所以我们可能用户滚动数组,不断替换,而算法思想是完全不变的//用递推来实现,要得到当前位的信息只与前一位有关,因为用滚动数组,只保存两位,不断滚动//dp[0][]表示前一位的信息,dp[1][]表示当前位的信息,每一位的数字只能为0和非0#include <cstdio>#include <cstring>#define MAX 1900 //位数#define LEN
阅读全文
摘要:DP+高精度 (和1009是一样的题目,不过数字的位数达到了180,所以要用高精度)同样是记忆化搜索实现,不过加入了高精度,一些细节地方就注意一下。我的代码写的不好,有点长有点乱…………#include <cstdio>#include <cstring>#define LEN 210 //高精度数组的大小#define MAX 210 //位数struct num{ int a[LEN],len; //a数组保存高精度}dp[MAX][15]; //最多180位,最高进制为10int N,K;void init(){ for(int i=1; i<N; i++)
阅读全文
摘要:DP,最大子矩阵和:先按列压缩为一维i,在用最大连续子序列和来求。在枚举列压缩求和的时候,为了提高速度,可以在输入的时候先保存下来,就不用每次都去计算,不过再代码中没有写另外这题不允许空矩阵,即至少要有一个元素,所以代码要做稍微的修改,就这样WA了几次/*最大子矩阵和,先压缩为一维再求最大子序列和,时间复杂度O(n^3)*/#include <cstdio>#include <cstring>#define N 1100#define INF 0x3f3f3f3fint a[N][N],s[N],n;void get_sum(int x ,int y){ for(int
阅读全文
摘要:DP(网格DP+空间压缩)题意:给你一个网格,最左下角下标为(0,0),最右上角坐标(N,M),每个格子都是100*100的正方形,从当前点可以向上下左右4个方向移动,如果恰好当前点有对角线,还可以向对角线移动。另外给你K个坐标,表示那些方格有对角线,这些坐标是方格的右上角的坐标,好像(50,50),其实就是(49,49)和(50,50)有斜线连接,(34,67)其实就是(33,66)和(34,67)有连接。现在问你从(0,0)到(N,M)的最短距离,结果四舍五入为整数DP思想还是很简单的,但是要压缩空间否则会MLE。先说说一开始的思路1.首先,从当前出发,不可能向左或者向下或者向左下走,只可
阅读全文
摘要:DP(记忆化搜索)第一次在Ural做题,所以选个简单的DP,无奈变量写错WA了两次,终于AC了题意:输入n和k,表示一个n位的k进制数,这个数字要符合两个条件,没有前导0(否则怎么算是n位数呢?),不能有两个或以上连续的0,问你一共有多少个这样的n位的k进制数这题,最直观的方法就是dfs,不断枚举,枚举到第n层就功德圆满了,然后再判断这个n位数是否符合我们的要求。但是可想而知是会超时的,那么怎么优化呢?第一,当前位的数字决定了下一位能出现什么数字,如果当前位非0,那么下一位[0,k-1]都可以,如果当前位为0则下一位[1,k-1],这样就可以在枚举的过程中避免掉两个连续的0的情况但是这个优化不
阅读全文