![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
刘汝佳算法竞赛入门经典
文章平均质量分 60
天地一扁舟
这个作者很懒,什么都没留下…
展开
-
算法竞赛入门经典:第九章 动态规划初步 9.2完全01背包
/*完全01背包:完全背包中每个物体可以被选择无限次,非恰好,状态dp[i][j]恰好可以由可能已经放入物品i的状态dp[i][j-goods[i].iWeight]转移而来,因此将遍历顺序该为顺序问题:采药。不同草药,采每一株需要一些时间,每一株有自己价值,如何让采到的价值最大。输入:第一行有两个整数T(1<=T<=1000)和M(1<=M<=100),T代表总共能够用来采药原创 2015-08-19 09:46:10 · 956 阅读 · 0 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.13困难的串
/*困难的串:如果一个字符串包含两个相邻的重复子串,则称它是“容易的串”,其他串成为“困难的串”。例如:BB,ABCDACABCAB,ABCDABCD都是容易的,而D、DC、ABDAB、CBABCBA都是困难的。输入正整数n和L,输出由前L个字符组成的、字典序第n个小的困难的串。例如,当L=3时,前7个困难的串分别为:A、AB、ABA、ABAC、ABACA、ABACAB、ABACA原创 2015-08-18 09:25:59 · 1998 阅读 · 0 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.11回溯法
/*回溯法:排列生成和子集枚举的两种方法:1递归,2遍历遍历:优点:简单,缺点:增大枚举量,检验所有解回溯法:含义 :递归时,将生成+检查过程结合 适合:问题分成步骤,步骤采用不太多选择回溯算法=递归枚举算法:分成若干步骤递归,若某一步无解,返回上一级调用,称为回溯。八皇后问题:在棋盘上放置8个皇后,使得她们互不攻击,此时每个皇后的攻击范围为同原创 2015-08-18 09:24:42 · 815 阅读 · 0 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.9位向量法
/*位向量法:构造一个位向量B[i],而不是直接构造子集A本身,其中B[i] = 1当且仅当i在子集A中。注意:此题不是求排列,而是求子集,这里n个元素有2^n-1个子集,因为空集无法打印出来输入:3输出:0 1 20 10 201 212*//*关键:1 if(pos == n)//凡是递归,先写递归出口,否则若写在后面原创 2015-08-18 09:22:48 · 517 阅读 · 0 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.6可重复的排列
/*生成可重集得到排列:把问题改成:输入数组P,并按字典序输出数组A各元素的所有全排列,则需要对上述程序进行修改--把P加到printPermutation的参数列表中,然后把代码中的if(iArr[i] == j) 和if(A[pos] == j)改成if(iArr[i] == P[j]) 和 iArr[pos] = P[j]bug1:如果数组中是重复的元素 1 1 1的话 ,因原创 2015-08-18 09:18:12 · 586 阅读 · 0 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.5枚举排列
/*枚举排列:输入整数n,按字典顺序从小到大的顺序输出前n个数的所有排列。两个序列的字典序大小关系等价于从头开始第一个不相同位置处的大小关系。例如,(1,3,2) <(2,1,3),字典序最小的排列是(1,2,3,...,n),最大的排列是(n,n-1,n-2,...,1)。n=3时,所有排列的排序结果是:(1,2,3)、(1,3,2)、(2,1,3)、(2,3,1)、(3,1,2),(3原创 2015-08-18 09:14:57 · 653 阅读 · 0 评论 -
算法竞赛入门经典:第六章 数据结构基础 6.2铁轨
/*铁轨:某城市有一个火车站,铁轨铺设如图所示。有n节车厢从A方向驶入车站,按进站顺序编号为1~n。你的任务是让它们按照某种特定的顺序进入B方向的铁轨并驶出车站。为了重组车厢,你可以借助中转站C。这是一个可以停放任意多节车厢的车站,但由于末端封顶,驶入C的车厢必须按照相反的顺序驶出C。对于每个车厢,一旦从A移入C,就不能再回到A了;一旦从C移入B,就不能再回到C了。换句话说,任意时刻,只有原创 2015-08-17 19:49:28 · 1121 阅读 · 0 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.2最大乘积
/*最大乘积:输入n个元素组成的序列S,你需要找出一个乘积最大的连续子序列。如果这个最大的成绩不是整数,应输出-1(表示无解)。1<=n<=18,-10<=Si<=10。输入:32 4 -35 2 5 -1 2 -1输出:820方法1:枚举起点和终点,注意大数要用long long表示方法2:动态规划max[i] = {max[i-1]*iArr[i],如果乘积大于0原创 2015-08-17 20:04:43 · 788 阅读 · 0 评论 -
算法竞赛入门经典:第六章 数据结构基础 6.13拓扑排序
/*拓扑排序:假设有n个变量,还有m个二元组(u,v),分别表示变量u小于v。那么,所有变量从小到大排列起来应该是什么样子的呢?例如有4个变量a,b,c,d。若一直a<b,c<b,d<c,则这四个变量的排序可能是a <d < c <b。尽管还有其他可能(如d<a<c<b),你只需要找出其中一个即可。思路:拓扑排序的本质是,寻找一个入度为0的节点,然后将以该入度为0的节点为起始节点线段原创 2015-08-17 20:01:10 · 750 阅读 · 0 评论 -
算法竞赛入门经典:第六章 数据结构基础 6.12迷宫路径
/*迷宫:一个网格迷宫由n行m列单元格组成,每个单元格要么是空地(用1表示),要么是障碍物(用0表示)。你的任务是找一条从起点到终点的最短移动序列,其中UDLR分别表示往上、下、左、右移动到相邻单元格。任何时候都不能在障碍格中,也不能走到迷宫之外。起点和终点保证是空地。n,m<=100。思路:从某点开始,计算出它到每个节点的最短距离,以及这些最短路径上每个节点的前一个节点*//*原创 2015-08-17 20:00:00 · 896 阅读 · 0 评论 -
算法竞赛入门经典:第六章 数据结构基础 6.11迷宫
/*迷宫:一个网格迷宫由n行m列单元格组成,每个单元格要么是空地(用1表示),要么是障碍物(用0表示)。你的任务是找一条从起点到终点的最短移动序列,其中UDLR分别表示往上、下、左、右移动到相邻单元格。任何时候都不能在障碍格中,也不能走到迷宫之外。起点和终点保证是空地。n,m<=100。输入:思路:采用bfs算法,设定初始结点和结束结点,它必须要有回溯标记,如果一旦不成功要将之前的原创 2015-08-17 19:59:06 · 780 阅读 · 0 评论 -
算法竞赛入门经典:第六章 数据结构基础 6.3移动小球
/*移动小球:我有小球,从左到右一次编号为1,2,3,...,n你可以执行两种指令:A X Y表示把小球X移动到小球Y的左边,B X Y表示把小球X移动到小球Y的右边。指令保证合法,即X不等于Y。输入小球个数n,指令条数m和m条指令,从左到右输出最后的序列。注意,n可能高达500000,而m可能高达100000输入:6 2A 1 4B 3 5输出:2 1 4 5 3 6关原创 2015-08-17 19:50:15 · 842 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.7二分查找之upperBound
/*写一个upperBound程序,当v存在时返回它出现的最后一个位置的后面的一个位置。如果不存在,返回这样一个下标i:在此处插入v(原来的元素A[i],A[i+1],..全部往后移动一个位置)后序列仍然有序。分析:iArr[mid] < iVal,只可能在右区间,且mid不可能,low = mid + 1,[mid+1,y]iArr[mid] = iVal,可能后面还有相原创 2015-08-18 09:46:33 · 564 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.3归并排序应用之逆序对数
/*逆序对数:给出一列数a1,a2,...,an,求它的逆序对数,即有多少个有序对(i,j),使得iaj。n可以高达10^6思路:分解成前后两个序列,统计后序列中每个元素与前面中每个元素的逆序对数,是一个叉乘书析:采用O(n^2)枚举超时,因为n很大。划分:将序列等分递归求解:统计i和j均在左边或者均在右边的逆序对个数合并:统计i在左边,但j在右边的个数原创 2015-08-18 09:39:56 · 945 阅读 · 0 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.20八数码问题之stl
/*八数码问题之stl:1set vis,这样只需要调用if(vis.count(s))来判断s是否在集合vis中,并用vis.insert(s)加入集合,用vis.remove(s)从集合中移除s。问题:并不是所有类型的State都可以作为set中的元素类型。set的元素必须定义"<"运算符,C语言原生的数组(包括字符数组)却不行。2如果数组不能转化为整数,自己声明结构体,重原创 2015-08-18 09:32:51 · 864 阅读 · 0 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.8子集生成
/*子集生成:给定一个集合,枚举它所有可能的子集。讨论范围:没有重复元素。增量构造法:一次选出一个元素放到集合中:*/#include #include #define MAXSIZE 1024//每次递归调用都输出当前集合,递归边界也不需要显式确定--如果无法继续添加元素,就不再递归。void printPermutation(int n,原创 2015-08-18 09:21:33 · 575 阅读 · 0 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.7解答树
/*解答树:以下的树显示了排列递归函数的调用过程。 (****) (1***) (2***) (3***)原创 2015-08-18 09:20:42 · 2139 阅读 · 1 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.16埃及分数
/*埃及分数:使用单位分数的和(如1/a,a是自然数)表示一切有理数。例如2/3 = 1/2 + 1/6,但不允许2/3 = 1/3 + 1/3,因为在加数中不允许有相同的。对于一个分数a/b,表示方法有很多种,其中加数少的比加数多的号,如果加数个数相同,则最小的分数越大越好。例如,19/45 = 1/5 + 1/6 + 1/18是最优方案。输入整数a,b(0<a<b<1000),原创 2015-08-18 09:27:42 · 836 阅读 · 1 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.18 广度优先搜索之八数码问题
/*八数码问题:编号为1~8的8个正方形滑块被摆成3行3列(有一个格子空留),如图所示。每次可以把与空格相邻的滑块(有公共边才算相邻)移到空格中,而它原来的位置就称为了新的空格。给定初始局面和目标局面(用0表示空格格),你的任务是计算出最少的移动步数。如果无法达到目标局面,则输-1.2 6 4 8 1 51 3 7 7 3 6 5 8 4原创 2015-08-18 09:30:26 · 2725 阅读 · 1 评论 -
算法竞赛入门经典:第七章 暴力求解法 7.18八数码问题之哈希去重
/*八数码问题之哈希去重:输入:2 6 4 1 3 7 0 5 88 1 5 7 3 6 4 0 2输出:31*//*关键:1 哈希:把结点变成整数,但不必是一一对应。设计一个哈希函数h(x),然后将任意结点x映射到某个给定的范围[0,M-1]的整数即可,其中M是程序员根据可用内存大小自选的。不同结点哈希值相同时,用链表组织哈希值相同的链表。2原创 2015-08-18 09:31:51 · 753 阅读 · 0 评论 -
算法竞赛入门经典:第十章 数学概念与方法 10.8约数的个数
/*约数的个数:给出正整数n的唯一分解式n = p1^a1*p2^a2*p3^a3...pk^ak,求n得正约数的个数分析:这里的正约数其实是被除数对于某个素因子pi,它的指数的可能性共有0,1,2,...,ai共ai+1种,因此正约数的个数=(a1+1)(a2+1)...(ai+1)12 = 2^2*3^156 = 2^3*7^1输入:1256原创 2015-08-19 09:58:42 · 576 阅读 · 0 评论 -
算法竞赛入门经典:第十章 数学概念与方法 10.2无平方因子的数
/*无平方因子的数:给出正整数n和m,区间[n,m]内的“无平方因子”的数有多少个?整数p无平方因子当且仅当不存在k>1,使得p是k^2的倍数。1<=n<=m<=10^12,m-n<=10^7分析:需要判断10^7个整数,每个整数需要时间判断是否没有平方因子。方法:利用素数筛选法,对不超过n的每个非负整数p,删除2p,3p,..,当处理完所有数之后,还没有被删除的就是素原创 2015-08-19 09:51:09 · 1615 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.16贪心之乘船问题
/*乘船问题:有n个人,第i个人重量为Wi。每艘船的最大载重量均为C,且最多只能乘两个人。用最少的船装载所有人。分析:若最轻的人与任何人都不能一起坐,那么没人独坐否则,应该选择能和他一起走的人里面最重的。贪心算法一定要证明:1:最轻的人i不和任何人坐,可以把J拉过来一起坐,总船数不会增加2:i和k同船,j是可以和i坐的人里面最重的,将j与k调换后,k后面所在的的原创 2015-08-19 09:20:10 · 1461 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.12非线性方程求根
/*非线性方程求根:一次向银行借a元钱,分b月还清。如果需要每月还c元,月利率是多少(按复利率计算)?例如借2000元,分4个月每月还510,则月利率为0.797%。答案应不超过100%。思路:设月利率为x,则第一个月还钱后还需还a(1+x)-c,重复b个月后可以得到方程输入:2000 4 510输出:0.797%*//*关键:1 使用猜原创 2015-08-19 09:18:04 · 978 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.8二分查找之范围统计
/*范围统计:给出n个整数xi和m个询问,对于每个询问(a,b),输出闭区间[a,b]内的整数xi的个数。思路:其实就是用lowerBound和upperBound分别确定a的下标和b的上标,用b-a如果两个都取到则是y-x+1两个都取不到是y-x前面取到,后面取不到是:y-x前面取不到,后面取得到:y-x+1大于等于a的第一个元素的下标是L。如果所有元原创 2015-08-19 09:14:03 · 702 阅读 · 0 评论 -
算法竞赛入门经典:第十章 数学概念与方法 10.3同余与模算术
/*同余与模算术:(a+b)mod n = (a mod n) + (b mod n)(a-b)mod n = [(a mod n) - (b mod n) + n] mod n 注意减法取模可能生成负数,因此加上n(ab) mod n = (a mod n)*(b mod n) mod n 注意乘法取模可能溢出,因此需要用long long 保存中间结果。不适原创 2015-08-19 09:52:46 · 711 阅读 · 0 评论 -
算法竞赛入门经典:第十章 数学概念与方法 10.7无关的元素
/*无关的元素:对于给定的n个数a1,a2,...,an,依次求出相邻两数之和,将得到一个新数列。重复上述操作,最后记过将变成一个数。问这个数除以m的余数与哪些数无关?例如n=3,m=2时,第一次求和得到a1+a2,a2+a3,再求和得到a1+2a2+a3,它除以2的余数和a2无关。1<=n<=10^5,2<=m<=10^9分析:最后的求和式是a1,a2,...,an的线性原创 2015-08-19 09:57:47 · 713 阅读 · 0 评论 -
算法竞赛入门经典:第十章 数学概念与方法 10.6递推之杨辉三角
/*杨辉三角与二项式定理:组合数C上m下n。与组合数最重要的两个东西:杨辉三角和二项式定理 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1将(a+b)^n展原创 2015-08-19 09:56:43 · 655 阅读 · 0 评论 -
算法竞赛入门经典:第十章 数学概念与方法 10.4大整数取模
/*大整数取模:输入正整数n和m,输出n mod m 的值。n <= 10^100,m<=10^9分析:把大整数写成自左向右的形式:1234=[(1*10 + 2)*10 + 3 ]*10 + 4,每步取模输入:1234567890123456789 100000000输出:23456789*//*关键:1 iSum = (int)原创 2015-08-19 09:54:21 · 964 阅读 · 0 评论 -
算法竞赛入门经典:第十章 数学概念与方法 10.1除法表达式
/*数论初步:除法表达式:给出这样的除法表达式:X1/X2/X3/.../Xk,其中Xi是正整数。除法表达式应当从左到右的顺序求和,例如表达式1/2/1/2的值为1/4。但可以在表达式中嵌入括号可以改变计算顺序,例如表达式(1/2)/(1/2)的值为1。输入X1,X2,..,Xk,判断是否可以通过添加括号,使表达式的值为整数。K<=10000,Xi<=10^9.分析:原创 2015-08-19 09:49:45 · 907 阅读 · 0 评论 -
算法竞赛入门经典:第九章 动态规划初步 9.1恰好型01背包
/*恰好型01背包问题:与01背包问题的唯一不同在于:初始化状态时,除了dp[0]=0之外,其余dp[j]全为INT_MAX,而且需要判断状态是否可以得到问题:采药。不同草药,采每一株需要一些时间,每一株有自己价值,如何让采到的价值最大。输入:第一行有两个整数T(1<=T<=1000)和M(1<=M<=100),T代表总共能够用来采药的时间,M代表山洞里的草药数目。原创 2015-08-19 09:44:48 · 619 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.17 贪心之选择不相交区间
/*选择不相交区间:数轴上有n个开区间(ai,bi)。尽量选择多个区间,使得这些区间两两没有公共点分析:假设有两个区间x,y。区间x完全包含y。应选x。按照bi从小到大的顺序给区间排序。贪心策略:一定要选第一个区间?区间排成:b1<=b2<=b3...情况1:a1>a2,区间2包含区间1,此时应选区间1,a1>ai,不选i情况2:a1<=a2原创 2015-08-19 09:21:30 · 604 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.9棋盘覆盖
/*棋盘覆盖:有一个2^k*2^k的方格棋盘,恰有一个方格是黑色的,其他为白色。你的任务是用包含3个方格的L型牌覆盖所有白色方格。黑色方格不能被覆盖,且任意一个白色方格不能同时被两个或更多牌覆盖。下面是L型牌的4种旋转方式。[][] [][] [] [][] [] [][]原创 2015-08-19 09:16:35 · 726 阅读 · 0 评论 -
算法竞赛入门经典:第十章 数学概念与方法 10.5幂取模
/*幂取模:输入正整数a、n和m,输出a^n mod m 的值,a, n , m <= 10^9输入:2 3 32 4 3输出:21*//*关键:1 if(0 == n)//递归出口是n==1时,表示为1的数字,防止陷入n=0,n/2=0的无限递归之中2 int x = powerMod(a,n/2,m);//这里采用递归,用n/2来缩原创 2015-08-19 09:55:10 · 760 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.4快速排序应用之第k小的数
/*第k小的数:输入n个整数和一个正整数k(1<=k<=n),输出这些整数从小到大排序后的第k个(例如k=1就是最小值)。n<=10^7思路:排序后再输入下标k-1的元素,nlogn = 10^7*300=3*10^9书析:利用快速排序分解[low,high]为[low,iPos-1]和[iPos+1,high]时,由于左边全部小于等于枢轴,只需判断左边序列:i原创 2015-08-18 09:42:38 · 704 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.2归并排序
/*归并排序:1 注意每次划分时候使用一个辅助数组输入:81 9 6 3 4 7 9 0输出:0 1 3 4 6 7 9 9*//*关键:1 void mergeSort(int* iArr,int low,int high,int* iTempArr)//注意,high是取不到的,因此传入的实参为数组长度n2 if(high - low >原创 2015-08-18 09:38:50 · 825 阅读 · 1 评论 -
算法竞赛入门经典:第六章 数据结构基础 6.4测试
/*测试:找一份完成相同功能的代码。对比测试,需要大量数据。stdlib.h中的rand(),生成[0,RAND_MAX]的均匀随机数,RAND_MAX>=32767*//*关键:1 int rand():产生0~RAND_MAX之间的伪随机数,rand()前面必须先调用srand(time(NULL)),time返回自1970年1月1日0点经过的秒数2 void srand(u原创 2015-08-17 19:51:28 · 443 阅读 · 0 评论 -
算法竞赛入门经典:第六章 数据结构基础 6.1卡片游戏
/*卡片游戏:桌上有一叠拍,从第一张牌(位于顶面的牌)开始从上往下依次编号为1~n。当至少还剩两张牌时进行以下操作:把第一张牌扔掉,然后把新的第一张放到整叠牌的最后。输入n,输出每次扔掉的牌,以及最后剩下的牌思路:设置剪枝数组,凡是扔掉的牌,置剪枝标记为真,循环结束条件为还剩一张牌,有两个循环:报数循环,每次报到的删除,大循环,每次超过7进入下一次循环关键:如何解决放在末尾的问题?用原创 2015-08-17 19:48:26 · 840 阅读 · 0 评论 -
算法竞赛入门经典:第八章 高效算法设计 8.6二分查找之lowerBound
/*深入:注意:对于二分查找的一个系列,high都是用数组长度来计算,真正是取不到的如果数组中多个元素都是v,上面的函数返回的是中间的一个。能不能呢个求出值等于v的完整区间呢?下面的程序当v存在时返回它出现的第一个位置。如果不存在,返回这样一个下标i:在此处插入v(原来的元素A[i],A[i+1],..全部往后移动一个位置)后序列仍然有序分析:最后的返回值不仅可能是x,原创 2015-08-18 09:45:28 · 530 阅读 · 0 评论 -
算法竞赛入门经典: 第三章 数组和字符串 3.4竖式问题
/*竖式问题:找出所有形如abc*de(三位数乘以两位数)的算式,使得在完整的竖式中,所有数字都属于一个特定的数字集合。输入:数字集合(相邻数字之间没有空格),输出:所有竖式。每个竖式前应有编号,之后有一个空行。最后输出解的总数。(本质上是一个乘法)输入:2357输出: 775X 33 23252325原创 2015-08-11 10:51:45 · 708 阅读 · 0 评论