算法设计与分析
二叉树
这个作者很懒,什么都没留下…
展开
-
输入一个高精度的正整数n,去掉其中任意s个数字后剩下的数字按原左右次序将组成一个新的正整数。编程对所给的n和s,寻找一种方案使得剩下的数字组成的新数最小。
#include <iostream>#include <string>using namespace std;//从字符串v中从下标j开始删除s个字符,删除的字符保存在s_del中void min_num(string &v, int &s,int j,string &s_del){ if ( 0 != s) { //如果j小于0则从第0个字符开始原创 2016-04-19 16:32:27 · 17776 阅读 · 2 评论 -
两种解法:找出n个自然数(1,2,3,……,n)中取r个数的组合。
例如,当n=5,r=3时,所有组合为: 1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5解法1:这种算法的时间复杂度为O(n^r),且r的大小已知,这样才能确定循环的层数。这种算法对于r比较小的时候可以考虑一下。int main(){ int n = 5; int r = 3; for原创 2016-04-01 09:17:20 · 10823 阅读 · 0 评论 -
素数环问题
把从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数。 C++代码:#include <iostream>#include <vector>#include <cmath>using namespace std;//打印结果void printSolution(const vector<int> &v){ for (vector<int>::const_iterat原创 2016-05-05 19:55:40 · 570 阅读 · 0 评论 -
背包问题之3
设有一个背包可以放入的物品重量为S,现有n件物品,重量分别为w1,w2,w3,……,wn。问:能否从这n件物品中选择若干件放入次背包,使得放入的重量之和正好为S。如果存在一种符合上述要求的选择,则称此背包问题有解(或称解为“真”),否则此问题无解(或解为“假”)。算法设计:递归枚举 背包问题3与背包问题1,2的根本差别在于:背包问题1所选的物品件数是固定的常量,备选物品件数可以是可知的变量原创 2016-05-16 20:57:18 · 2920 阅读 · 0 评论 -
设计一个算法,把一个真分数表示为埃及分数之和的形式。所谓埃及分数是指分子为1的分数。如7、8=1/2+1/3+1/24。
数学模型:将一个真分数F表示为A/B;做B/A的整除运算,商为D,余数为K,它们之间的导出关系如下: B=A*D+k B/A=D+K/A#include <iostream>using namespace std;int main(){ int a,b; int c,d; while (cin>>a>>b) { if (a >=原创 2016-04-20 21:53:06 · 8613 阅读 · 0 评论 -
背包问题之2
小明有一只能装10千克的背包,现在有白菜一颗5千克,猪肉一块2千克,酱油1.7千克,一条鱼3.5千克,白糖一袋1千克,菜油一桶5.1千克。请编写一个算法,设计小明的背包所装东西的总重量最重。 算法思想: 在上一种背包问题中固定选取3种物品,可以用三重循环枚举这3件物品,从中找到问题的解。该例就无法照搬上面的算法了,但仍然可以延用上一种背包问题的设计方法。既然固定项的各种情况可以进行枚举,原创 2016-05-13 19:49:50 · 920 阅读 · 0 评论 -
数列极差问题
在黑板上写了n个正整数排成的一个数列,进行如下操作:每次擦去其中的两个数a和b,然后在数列中加入一个数a*b+1,如此下去直至黑板上剩下一个数,在所有按这种操作方式最后得到的数中,最大的记为max,最小的记作min,则该数列的极差定义位m=max-min。问题分析:下面通过实例来认识题目中描述的计算过程。对3个具体的数据3,5,7,讨论,可能有一下3种结果: (3*5+1)*7+1 = 113,(原创 2016-04-19 19:22:36 · 859 阅读 · 0 评论 -
背包问题之1
在9件物品中选出3件使其重量和与700克之差的绝对值最小。这里有在n个数中找出r个数的组合的两种方法,根据这两种方法对上面的问题对应有两种解法,下面给出的代码只是其中一种。C++源代码: 算法说明:嵌套循环中i,j,k的变化过程如下: (0,1,2)、(0,1,3)、……、(0,1,8) (0,2,3)、…原创 2016-05-13 19:14:08 · 525 阅读 · 0 评论 -
给定一组数,要求从中找出第k小的元素
分析: 这里通过快速排序算法来解决次问题。记一趟快速排序后,左子集中的元素个数为nleft,则选择问题,可能是一下几种情况之一: 1) nleft等于k-1,则枢纽值即为所求; 2) nleft大于k-1,则继续在左子树中找; 3) nleft小于k-1,则继续在右子集中找下面是C++代码实现:#include <iostream>#include <vector原创 2016-04-19 11:49:14 · 2393 阅读 · 0 评论 -
找出1到n所有不重复的排列,即n的全排列。
解法一:#include <iostream>#include <vector>using namespace std;//打印结果void printSolution(const vector<int> &v){ for (vector<int>::const_iterator it = v.begin();it != v.end();++it) { co原创 2016-05-05 21:20:18 · 6273 阅读 · 0 评论 -
背包问题之4
部分背包问题:一个商人带着一个能装m千克的背包去向下收购货物,准备将这些货物卖到城里获利。现有n种货源,且知第i种货物有wi千克,可获利pi元。请编写算法帮助商人收购货物,以获取最高的利润。**算法设计:贪婪算法。 当w1+w2+……+wn小于等于m时,收购所有货物即可,但出现了w1+w2+……+wn大于m的情况,商人只能选择一些货物购买,假设每种货物都可以分成需要的任意一小部分放入背包(这类问题原创 2016-05-16 22:05:14 · 788 阅读 · 0 评论 -
有两艘船需要装运的n箱货物,第一艘船的载重量是c1,第二艘船的载重量是c2,wi是货箱i的重量,且w1+w2+……+wn<=c1+c2。
希望确定是否有一种可将所有n个货箱全部装船的方法。若有的话,找出该方法。 主要思想:即求第一艘船的最大装载量问题。每种货物有装和不装两种情况,n个货物的取舍组合共2^n次个分支。 C++代码:#include <iostream>#include <queue>#include <vector>using namespace std;double MaxLoading(const vect原创 2016-05-06 21:37:10 · 5231 阅读 · 1 评论 -
猴子选大王(3种超简单的方法)
17个猴子围成一圈,从某个开始报数1-2-3-1-2-3-……报“3”的猴子就被淘汰,游戏一直进行到圈内只剩一只猴子它就是猴大王了。方法一: 小技巧:用数组来记录猴子是否在圈内的状态:在圈内记为“1”,不在圈内记为“0”。并以累加数组元素值来模拟报数过程,这样就减少了判断猴子是否在圈内的操作。 C++代码如下:#include <iostream>#include <vector>using原创 2016-05-09 11:54:01 · 67311 阅读 · 3 评论 -
大整数的相加、相减和相乘
#include <iostream>#include <string>using namespace std;string _sub(string s1, string s2);//比较两个正数的大小inline int compareData(const string &s1,const string &s2){ if (s1.length()>s2.length()) ret原创 2016-06-28 12:29:41 · 570 阅读 · 0 评论 -
求数列的最大子段和的两种方法(包括时间复杂度为线性时间的算法)
方法一: C++代码:#include <iostream>#include <vector>using namespace std;const int N = 17;int max_sub_sum(const vector<int> &v, int &best_i, int &best_j){ int n = v.size(); //当前最大子段和 int sum原创 2016-04-12 16:36:25 · 3596 阅读 · 0 评论 -
8皇后问题的两种解法
C++代码: 解法一:#include <iostream>#include <vector>using namespace std;bool check(const vector<int> &v, int k){ for (int i=0;i<k;++i) { //如果第i个和第k个的皇后同在主对角线或者副对角线或者同在一列 if (abs(原创 2016-05-04 17:21:15 · 3345 阅读 · 0 评论 -
LeetCode第21题之Generate Parentheses(两种解法)
C++代码:#include <vector>#include <iostream>#include <string>using namespace std;class Solution {private: //保存结果 vector<string> res;public: void fun(int deep, int n, int leftNum, int lef原创 2016-06-02 11:28:54 · 433 阅读 · 0 评论 -
数塔问题
先贴出运行结果: C++代码:#include <iostream>#define N 50using namespace std;//a[.][.][0]存储原始数据//a[.][.][1]存储存储动态规划过程//a[.][.][2]存储最优化路径int main(){ int a[N][N][3]; cout<<"please input the number原创 2016-04-23 20:22:02 · 330 阅读 · 0 评论 -
背包问题之6
背包问题之5中的算法只给出了最大利润的值,而没有给出最大利润下,背包所装物品的方案。下面除了通过回溯算法改进上一个算法的效率,还实现了给出背包所装物品方案的功能。 算法思想: 为找到最大的获利情况,先用最简单的蛮力算法回溯法来解决这个问题。不同于递归算法,递归算法是找大规模问题与小规模问题的关系,回溯法是对问题解空间进行搜索的算法。 C++代码:#include <iostream>#inc原创 2016-05-18 21:34:53 · 452 阅读 · 0 评论 -
背包问题之5
0/1背包问题:问题同背包问题4,只是约定物品不允许拆零。 算法设计5:递归枚举解0/1背包问题。 算法5的设计思想与背包问题3类似,为找出大规模与小规模问题的关系,对于每一件物品考虑仅有两种可能“选择或不选择”,当然选择某物品的前提是背包容量可以容纳它。 C++代码:#include <iostream>#include <vector>using namespace std;//此函数原创 2016-05-18 20:22:47 · 311 阅读 · 0 评论 -
有如图所示的七巧板,试设计算法,使用至多4种不同颜色对七巧板进行涂色(每块七巧板一种颜色),要求相邻区域的颜色互补相同,打印输出所有可能的涂色方案。
C++代码:#include <iostream>#include <vector>using namespace std;//邻接矩阵表const int data[7][7] = {{0,1,0,0,1,0,1},{1,0,0,1,0,1,0},{0,0,0,1,0,0,1},{0,1,1,0,0,1,1},{1,0,0,0,0,0,1},{0,1,0,1,0,0,0},{1,0,1,1原创 2016-04-29 14:58:30 · 7138 阅读 · 0 评论 -
走迷宫问题(深度优先遍历 + 广度优先遍历)
迷宫是许多小方格构成的矩形,在每个小方格中有的是墙(用1表示),有的是路(用0表示)。走迷宫就是从一个小方格沿上、下、左、右四个方向到邻近的方格,当然不能穿墙。设迷宫的入口是在左上角(1,1),出口是在右下角(8,8)。根据给定的迷宫,找出一条从入口到出口的路径。解法一(深度优先遍历,打印所有可行的路径):#include <iostream>using namespace std;int maz原创 2016-04-29 08:54:26 · 17717 阅读 · 1 评论 -
已知若干个城市的地图,求从一个城市到另外一个城市的路径,要求路径中经过的城市最少。
算法设计:图的广度优先搜索类似于树的层次遍历,逐层搜索正好可以尽快找到一个结点与另外一个结点相对而言最直接的路径。所以此问题适应广度优先算法。 例如:下图是从城市A到城市H的交通图。从图中可以看出,从城市A到城市H要经过若干个城市。先要找出一条经过城市最少的一条线路。图的邻接矩阵如下表所示,1表示能走,0表示不能走。 C++代码:#include <iostream>#include <vec原创 2016-04-28 21:24:46 · 7866 阅读 · 0 评论 -
填写运算符
输入任意5个数x1,x2,x3,x4,x4两个相邻数之间天上一个运算符。在填入4个运算符“+、-、*、/”后,使得表达式值为一个指定值y(y由键盘输入)。求出所有满足条件的表达式。问题分析:在每两个相邻数之间尝试所有的运算符。#include <iostream>#include <vector>using namespace std;int main(){ string s =原创 2016-04-07 16:04:05 · 547 阅读 · 0 评论 -
3位老师对某次数学竞赛进行了预测。他们的预测如下。
甲说:学生A得第一名,学生B得第三名。 乙说:学生C得第一名,学生D得第四名。 丙说:学生D得第二名,学生A得第三名。 竞赛结果表明,他们都说对了一半,并且无并列名次,试编程输出a,b,c,d各自得名次。 分析:这题和上一题差不多,只不过上一题只需要一个参数(小偷的编号),而这一题需要4个参数(一、二、三、四名)。需要注意的是在判断语句中“加号”的优先级是高于“==”,所以下面的判断条件要加原创 2016-04-07 10:00:44 · 4376 阅读 · 0 评论 -
警察局抓了a,b,c,d 4名偷窃嫌疑犯,其中只有一人是小偷。审问中,a说:“我不是小偷。”b说:“c是小偷。”c说:“小偷肯定是d。”d说:“c在冤枉人。”
现在已知4个人中有3个人说的是真话,一个人说的是假话,问到底谁是小偷?问题分析:用枚举尝试法来解决。 算法设计:用变量x存放小偷的编号。 四个人所说的话就可以表示成如下四句话: a说的话: x != 1 b说的话: x == 3 c说的话: x == 4 d说的话: x != 4#include <iostream>#include <vector>using namespace s原创 2016-04-06 15:30:04 · 21505 阅读 · 1 评论 -
求任意三个数的最小公倍数
#include <iostream>#include <vector>using namespace std;int maxNum(int x, int y, int z){ if (x>y && x>z) return x; else if(y>x && y>z) return y; else return z;}原创 2016-04-06 15:09:35 · 2120 阅读 · 0 评论 -
有3n个花盆,红色、蓝色和黄色的各n个。开始时排列的顺序是混乱的,如黄、红、蓝、黄、黄、蓝、黄、红、红……
请编写意程序:将各花盆按红、黄、蓝、红、黄、蓝……的顺序排列,而且要求花盆之间的交换次数最少。分析:交换两个变量A、B的值徐需要交换3次,交换3个变量的值需要交换4次。实现要点:实现中并不用专门统计交换次数,而是将3n个数据存储在n*3的二维数组空间中,这样第一列应放红花盆、第二列应该放黄花盆、第三列应该放蓝花盆。程序由直接交换(一次直接交换需要交换3次)和循环交换(一次循环交换需要交换4次)两部分原创 2016-04-06 10:34:08 · 1383 阅读 · 0 评论 -
螺旋阵:任意给定n值,按如下旋转的方式输出方阵。
n=3 输出: 1 2 3 8 9 4 7 6 5n=4 输出: 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 //思路,i代表外层循环,j表示i层内每边中行或列的下标#include <iostream>#include <string>#define N 100using namespace std;int m原创 2016-04-05 21:10:23 · 3413 阅读 · 0 评论 -
游戏问题
12个小朋友手拉手站成一个圆圈,从某一个小朋友开始报数,报到7的那个小朋友退到圈外,然后他的下一位重新报“1”。这样继续下去,直到最后只剩下一个小朋友。求解这个小朋友站在什么位置上。#include <iostream>using namespace std;int main(){ int state[12]; for (int i=0;i<12;++i) {原创 2016-04-01 18:49:02 · 673 阅读 · 0 评论 -
任何一个正整数都可以用2的幂次方表示
例如:137=2^7+2^3+2^0,约定a^b可表示为a(b),则137可表示为:2(7)+2(3)+2(0),进一步7=2^2+2+2^0,3=2+2^0。所以137最终可以表示为2(2(2)+2+2(0))+2(2+2(0))+2(0)。输入:正整数(n<=20 000).输出:符合约定的n的0,2表示(在表示中不能有空格)。算法设计:由于不知道数据的位数,加上对数据还是从低位到高位的操作原创 2016-03-31 19:57:32 · 12657 阅读 · 0 评论 -
有10箱产品,每箱有1000件,其中正品每件100克。其中有几箱是次品,每件次品比正品轻10克,问能否用秤只称一次,就找出哪几箱是次品?
#include <iostream>#include <vector>//#include <string>using namespace std;int main(){ int n; cout<<"input the number of boxes:"; cin>>n; //标准总重量 long w1 = 0; long w2 = 0;原创 2016-04-07 18:36:03 · 4349 阅读 · 0 评论 -
编写算法对输入的一个整数,判断它能否被3,5,7整除,并输出一下信息之一:
能同时被3,5,7整除; 能被其中两个数(要指出哪两个数)整除; 能被其中一个数(要指出哪一个数)整除; 不能被3,5,7任一个整除。#include <iostream>using namespace std;int main(){ int tmp; cout<<"please enter a number:"; while(cin>>tmp) {原创 2016-04-07 19:06:31 · 42178 阅读 · 4 评论 -
分而治之算法
适合分治法策略的问题 (1) 能将n个数据分成k个不同的子集合,且得到的k个子集合是可以独立求解的子问题,其中1Divide_Conquer(n){ if (n<=n0) { 解子问题; return(子问题的解); } for (i=1;i<k;++i) { 分解原问题为更小的子问题原创 2016-04-12 09:53:11 · 428 阅读 · 0 评论 -
求一个数列(数列中的每个数不相同)的最长不下降子序列。
例如:整数组成的数列为3,18,7,14,10,12,23,41,16,24。则3,18,23,24就是一个长度为4的不下降序列。同时还有3,7,10,12,16,24或3,7,10,12,23,41都是长度为6的最长不下降序列。 请编写算法求出一个数列的最长不下降序列。分析:若从a(i)开始,此时最长不下降序列应该按下列方法求出: 再a(i+1),a(i+2),…,a(n)中,找出一个起始数据原创 2016-04-28 09:39:48 · 1855 阅读 · 0 评论 -
例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列。给定两个序列A和B,称序列Z是A和B的公共子序列,是指Z同是A和B的子序列。编写算法求一直两序列A和B的最长公共子序列。
分析: v[i][j]存储序列“a0,a1,…,ai-1”, “b0,b1,…,bj-1”的最长公共子序列的长度。 则v[i][j]的计算如下: (1). v[i][j] = 0; (2). v[i][j] = v[i-1][j-1]+1, 如果a[i-1] = b[j-1] (3). v[i][j] = max(v[i-1][j],v[i][j-1]),a[i-1] != b[j-1]C原创 2016-04-26 14:50:39 · 2101 阅读 · 0 评论 -
求一组数的第二小的数据
算法设计:在用二等分法分解的两个子集中,无论只选取第二小数据或只选取最小的数据,合并处理后都有可能得不到原问题的正确解。但若在两个子集中都选取最小的两个值,那么,原问题中第二小的数据则一定在这4个数中。C++源代码:#include <iostream>#include <vector>using namespace std;//在v中下标[i,j]之间,选出最小的两个数,最小的数保存在min1原创 2016-04-13 19:09:57 · 2225 阅读 · 1 评论 -
大整数相乘
思路:以s1=“999”,s2=”66”为例,见下图。C++代码实现:#include <iostream>#include <vector>#include <string>using namespace std;//vector<int> stoint(const string &s){ vector<int> v; size_t sz = s.size();原创 2016-04-12 19:20:10 · 371 阅读 · 0 评论 -
资源分配问题
设有资源n(n为整数),分配给m个项目,gi(x)为第i个项目分得资源x(x为整数)所得的利润。求总利润最大的资源分配方案,也就是解下列问题: max z = g1(x1)+g2(x2)+……+gm(xm) x1+x2+……+xm = n, xi为整数,i=1,2,3,……,m 函数gi(x)以数据表的形式给出。 C++代码:#include <iostream>#define N 100原创 2016-04-25 11:44:16 · 4403 阅读 · 0 评论 -
求两个数的最大公约数和最小公倍数的一种超级简单的方法
数学建模:辗转相除法 不妨设两个整数a>b且a除以b商x余c;则a-bx=c,不难看出a,b的最大公约数也是c的约数(因为一个数能除等式左边就一定能除等式的右边),则a,b的最大公约数与b,c的最大公约数相同。最大公约数的C++代码:#include <iostream>using namespace std;int main(){ unsigned a,b,c; while原创 2016-04-08 11:39:32 · 1456 阅读 · 0 评论