
算法与数据结构
活在阳光下
这个作者很懒,什么都没留下…
展开
-
杨辉三角
杨辉三角是一个由数字排列成的三角形数表:/* yh-2d.c - 二维数组迭代 */#include#define M 10 // 行数 #define PYRAMID // 金字塔,会额外填充空格 #define REVERSE // 反向再来一次,得到菱形int main(void){ int a [M][M], i, j; // 二维数组和循环变量,a[行原创 2016-03-10 19:09:41 · 290 阅读 · 0 评论 -
水手分椰子问题
五个水手来到一个岛上,采了一堆椰子后,因为疲劳都睡着了。一段时间后,第一个水手醒来,悄悄地将椰子等分成五份,多出一个椰子,便给了旁边的猴子,然后自己藏起一份,再将剩下的椰子重新合在一起,继续睡觉。不久,第二名水手醒来,同样将椰子了等分成五份,恰好也多出一个,也给了猴子。然而自己也藏起一份,再将剩下的椰子重新合在一起。以后每个水手都如此分了一次并都藏起一份,也恰好都把多出的一个给了猴子。第二天,五个原创 2016-04-13 21:32:42 · 12166 阅读 · 1 评论 -
杨辉三角
杨辉三角的每一行的首尾两数均为1;第k行共有k个数,除首尾两数外,其余各数均为上一行的肩上两数之和。#include void main(){ int n,i,j,k,a[20][20]; printf("请输入行数:"); scanf("%d",&n); for(i=1;i<=n;i++) { a[i][1]=1; a[i][i]=1;原创 2016-04-13 21:22:34 · 628 阅读 · 0 评论 -
统计n!尾部零
试统计正整数n的阶乘n!=1*2*...*n的尾部连续零的个数。(1)基本求积运算算法要点:注意到输入整数n规模可能较大,n!尾部零的个数也就较多,设计a数组存储n!的各位数字,a[1]存储个位数字,a[2]存储十位数字,以此类推。首先通过常用对数累加和s=lg2+lg3+...+lgn确定n!的位数m=s+1,即a数组元素的个数。设置两重循环,模拟整数竖式乘法实施各数组元素的原创 2016-04-12 16:00:41 · 1383 阅读 · 0 评论 -
拆分为连续正整数之和
试把一个正整数n拆分为若干个(不少于2个)连续正整数之和。例如n=15,有三种拆分:15=1+2+3+4+5,15=4+5+6,15=7+8.对于给定的正整数n求出所有符合这种拆分要求的连续正整数序列的个数。(1)基本求和算法算法要点:定义变量s实施连续求和,设计i(1~(n-1)/2)循环为连续求和的起始项,j(i~(n+1)/2)为连续求和的累加项。在j循环中每加一项j原创 2016-04-12 14:22:41 · 2099 阅读 · 0 评论 -
不能用加减乘除做加法
对于这样的问题我们可以分为三部。第一步:把两个数字做异或运算^第二步:把两个数字做位于运算,然后把结果向左移一位,第三步:把前两步得到的结果相加,一直重复到第二步得到的结果为0为止。// AddTwoNumbers.cpp : Defines the entry point for the console application.//// 《剑指Offer——名企面试原创 2016-03-13 15:42:03 · 399 阅读 · 0 评论 -
求1+2+3+4+++++++n
要求不能使用for、while、if、else、switch、case等关键字,以及条件判断语句(A?B:C)方法一:我们可以用构造函数来完成这个事情,我们为了一个类创建n个对象,设置一个类的静态变量,用new分配内存(因为new自动调用构造函数)方法二:我们可以用虚函数来求解,定义两个函数,一个函数充当递归函数的角色,另一个函数处理终止递归的情况,我们需要做的就是在这两个原创 2016-03-13 15:22:09 · 1206 阅读 · 0 评论 -
圆圈中最后剩下的数字(约瑟夫环问题)
0,1,2,3 n-1这n个数字排成一个圈,从数字0开始每次从这个圆圈里删除第m个数字。求这个圆圈中最后剩下的数字。既题目是一个数字圆圈,我们很自然的想到就是用一个数据结构来模拟这个圆圈。环形链表是最好的办法,但是如果我们不能使用标准模板库里的数据容器来模拟环形链表,我们可以自己实现一个链表也不是很难呐。我们可以用模板库中的std::list来模拟环形链表。每当迭代器扫描到原创 2016-03-13 12:16:00 · 732 阅读 · 0 评论 -
扑克牌的顺子问题
从扑克牌中随意抽五张牌,判断是不是一个顺子,即这五张牌是不是连续的。2-10为数字本身,A为1,J为11,Q为12.K为13.而大小王可以看成任意的数字。我们需要把这五张牌看成是数字的形式,我们领大小王看成0,我们假定大小王可以代替任意的数字,这样先把抽出的五张牌按照数字大小的顺序排成一个有序的队列,然后统计里面的0的数字个数,还有其他数字的间隔个数字个数,比如1和4之间间隔了2,3,原创 2016-03-13 11:29:48 · 1189 阅读 · 0 评论 -
两个链表的第一个公共节点
输入两个链表,找出它们的第一个公共的节点。碰到这种题的时候千万不要用挨个遍历的方法,时间复杂度高对于两个有相同节点的链表的形状一定是Y。而不是X。然后还可能一个链表长一个链表短,我们可以求出差值,然后让长链表先走差值的长度,然后在挨个比较就可以了。这样时间复杂度就小很多了:// FirstCommandNodesInLists.cpp : Defines the entry p原创 2016-03-12 16:22:50 · 340 阅读 · 0 评论 -
数组中的逆序对
在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求这个数组中逆序对的总队数。扫描数组的方法并不高效,时间复杂度为O(N*N),我们可以考虑拆分数组,每次平均拆分成两组,一直拆到每组数组均有一个元素,我们设置两个指针分别指向两个字数组的末尾,每次比较指针指向的数字,如果第一个数字大于第二个数字,则构成逆序对,并且逆序对的数字等于第二个数组中的数原创 2016-03-12 16:03:50 · 391 阅读 · 0 评论 -
第一个只出现一次的字符
在字符串中找到一个只出现一次的字符。如输入“abaccdeff” 输出结果为'b'。最直观的想法就是从头开始扫描这个字符串中的每个字符。当访问到某个字符的时候拿这个字符和后面的每个字符相比较,如果在后面没有发现重复的字符,则该字符就是只出现一次的字符,不过这种方法时间复杂度是O(n*n)。我们可以定义一个哈希表,哈希表的键值是字符,而值是数字。然后扫描字符串两次,第一次扫描字符串时原创 2016-03-12 15:35:05 · 302 阅读 · 0 评论 -
丑数的问题
题目:我们把只包含因子2,3,5的数称为丑数。求按从小达到的顺序的第1500个丑数。习惯上我们把1当作第一个丑数。这个问题乍看不是很难,很容易想到快速的方法求解,可是效率总是很低!根据题目可以看出丑数是有规律的,都是2或3或5的倍数,除了1之外,那么我们就可以利用这一个规律求某个范围内的丑数,而不是每个数字都判断一下。如何求一个丑数数组的下一个丑数,下一个丑数肯定比之前最后原创 2016-03-12 15:16:15 · 577 阅读 · 0 评论 -
两个数字判断大小
有两个int型数据A和B,在不借助于if ?: swich等判断条件时求出最大的值::方案一:int max=((a+b)=abs(a-b))/2方案二:int c=a-b;c=unsigned(c)>>(sizeof(int)*8-1)原创 2016-03-11 18:53:19 · 2239 阅读 · 0 评论 -
八皇后的问题
首先介绍一下八皇后的问题。这是一个古老而著名的问题,指的是在一个8X8的国际象棋棋盘上,有八个皇后,每个皇后占一个;要求皇后之间不会出现相互攻击的现象,即不能有两个皇后处在同一行、同一列或同一对角线上。问一个有多少种不同的排列方法?下面是代码:#includeusing namespace std;static int gEightQueen[8] = { 0 }, gCount = 0;原创 2016-03-10 21:17:10 · 398 阅读 · 0 评论 -
字符串转换为数字
#include #include using namespace std;void ConvertLong(string n,long&);int main(){ string a="1234585"; long value=0; ConvertLong(a,value); cout<<value<<":"<<value+1<<endl; return 0;}void原创 2016-03-10 19:54:43 · 366 阅读 · 0 评论 -
求素数
首先素数是除了1和自身之外,在没有可以被整除的数:#include #include using namespace std;void GetPrimer(long n,vector& primer);int main(){ vector primer; GetPrimer(100,primer); vector::iterator it=primer.begin(); whi原创 2016-03-10 19:44:50 · 322 阅读 · 0 评论 -
任意进制转换二进制
#include #include #include using namespace std;void fconvert(long n,vector&);int main(){ vector bit; //保存转换之后的结果 fconvert(11,bit); vector::iterator it=bit.begin(); while(it!=bit.en原创 2016-03-10 19:33:49 · 1529 阅读 · 0 评论 -
欧几里德算法求最大公约数
欧几里德算法依据的算法定理是:gcd(m,n)=gcd(n,m mod n);(1) m除以n得余数r,若r为0,则n就是所求得最大公约数(2) 若r不等于0,以n为m,r为n继续(1)欧几里德算法又称为辗转相除法:代码如下#include void main(){ long m,n,c,r; printf("请输入整数m,n:"); scanf("%d %d",&m,原创 2016-04-11 19:22:31 · 1771 阅读 · 0 评论