身为程序员还记得C语言经典算法(附带答案)吗?

  • Post author:
  • Post category:其他



前言:C语言中有有许多经典的算法,这些算法都是许多人的智慧结晶,也是编程中常用的算法,这里面包含了众多算法思想,掌握这些算法,对于学习更高级的、更难的算法都会有很大的帮助,会为自己的算法学习打下坚实的基础。


1、猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。程序分析:采取逆向思维的方法,从后往前推断。

void MonkeyEatPeach()
{
	int day,x1,x2;
	day=9;
	x2=1;
	while(day>0)
		 {x1=(x2+1)*2;/*第一天的桃子数是第2天桃子数加1后的2倍*/
	 x2=x1;
	 day--;
	 }
	printf("the total is %d\n",x1);
}


2、将10进制的数转换为2-16进制。

//将10进制数转换为其它进制
void From10baseTransformTo1_16(int m,int base)
{
	char num[] = "0123456789ABCDEF";
	char result[30] = {0};
	int len = 0;
	char temp;
	int start = 0;
	int end = len;
	
	while(m)                //辗转相除,先存正向的余数
	{
		result[len++] = num[m%base];
		m = m / base;
	}
	
    start = 0;
	end = len-1;
	while(start < end)   //字符串翻转
	{
		temp = result[start];
		result[start] = result[end];
		result[end] = temp;
		start++;
		end--;
	}
  
	start = 0;
	for(start = 0; start < len; start++)
    	printf("%c",result[start]);
	printf("\n");
 
}


3、将一个正整数分解质因数。例如:输入90,打印出90=2

3

3*5。

//将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
void DivideFactor(int n)
{
	int i; 
	printf("\nplease input a number:\n"); 
	scanf("%d",&n); 
	printf("%d=",n); 
 
	for(i=2;i<=n;i++) 
	{ 
		while(n!=i) 
		{ 
			if(n%i==0) 
			{ 
				printf("%d*",i); 
		    	n=n/i; 
			} 
			else 
			{
				break;
			}
		} 
	} 
	printf("%d",n);
 
}


4、不依赖第三个变量,实现两个整数交换。

/不依赖第三个变量,实现两个整数交换
//第一种方法
void Exchange1(int* a,int* b)
{
	*a = *a + *b;
	*b = *a - *b;
	*a = *a - *b;
}
//第二种方法(用位运算)
void Exchange2(int* a,int* b)
{
	*a = *a ^ *b;
	*b = *a ^ *b;
	*a = *a ^ *b;
}


5、打印出三位的”水仙花数”,所谓”水仙花数”是指一个N位数,其各位数字立方和等于该数。

//打印出三位的"水仙花数",所谓"水仙花数"是指一个N位数,其各位数字立方和等于该数 
void WaterFlowerNumber()
{
	int i,j,k,n;
	printf("Water flower number is:");
	for(n = 100; n < 1000; n++)
	{
		i = n/100; //分解百位
		j = n/10 % 10; //分解十位
		k = n % 10; //分解个位
		if(i*i*i + j*j*j + k*k*k == n)
			printf("%-5d\n",n);
	}
}


6、求两个数的最大公约数和最小公倍数。

//求两个数的最大公约数
int gcd(int a,int b)
{
	int r;
	if(a < b)        //a < b,则交换两个数
	{
		int temp = a;
		a = b;
		b = temp;
	}
 
	r = a % b;
	while(r != 0)
	{
		a = b;
		b = r;
		r = a % b;
	}
	return b;
}
//求两个数的最小公倍数数
int lcm(int a,int b)
{
	return a*b/gcd(a,b);
}


7、求一个数的阶乘。

//递归求阶乘
long factorial(long n)
{
	if(n <= 1)
		return 1;
	else 
		return n * factorial(n-1);
}
//非递归求阶乘
long Factorial(long n)
{
	int sum,i;
	sum = 1;
	for(i = 1; i <= n; i++)
		sum *= i;
	return sum;
}


8、输入某年某月某日,判断这一天是这一年的第几天?

//输入某年某月某日,判断这一天是这一年的第几天? 
/*  
程序分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊 
情况,闰年且输入月份大于3时需考虑多加一天。
*/
int GetDays(int year,int month,int day)
{
	int sum = 0;
	int i;
	for(i = 1; i < month; i++)      //将前几个月天数相加
		sum += GetMaxDay(year,month);
	sum = sum + day;  //加上本月的天数,就是总天数
	return sum;
}


9、获得某年、某月的最大天数。

//获得某年、某月的最大天数
int GetMaxDay(int year,int month)
{
	switch(month)
	{
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12:
		return 31;
	case 4:
	case 6:
	case 9:
	case 11:
		return 30;
	case 2:
		return IsLeapYear(year)?29:28;		
	default:return -1;
	}
}


10、判断某一年是否是闰年。

//判断某一年份是否是闰年
int IsLeapYear(int year)
{
	return (year % 400 == 0 || (year % 4 == 0) && (year % 100 != 0));
}


下一篇C语言经典算法问题:



河内之塔

:说明河内之塔(Towers of Hanoi)是法国人M.Claus(Lucas)于1883年从泰国带至法国的,河内为越战时北越的首都,即现在的胡志明市;1883年法国数学家 Edouard Lucas曾提及这个故事,据说创世纪时Benares有一座波罗教塔,是由三支钻石棒(Pag)所支撑,开始时神在第一根棒上放置64个由上至下依由小至大排列的金盘(Disc),并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将毁损,而也就是世界末日来临之时。

**解法:**如果柱子标为ABC,要由A搬至C,在只有一个盘子时,就将它直接搬至C,当有两个盘子,就将B当作辅助柱。如果盘数超过2个,将第三个以下的盘子遮起来,就很简单了,每次处理两个盘子,也就是:A->B、A ->C、B->C这三个步骤,而被遮住的部份,其实就是进入程式的递回处理。事实上,若有n个盘子,则移动完毕所需之次数为2^n – 1,所以当盘数为64时,则所需次数为:264- 1 = 18446744073709551615为5.05390248594782e+16年,也就是约5000世纪,如果对这数字没什幺概念,就假设每秒钟搬一个盘子好了,也要约5850亿年左右。

在这里插入图片描述



版权声明:本文为weixin_52183917原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。