新手级基础算法扩展(持续更新)

判断闰年

闰年的概念:能被四整除且不能被一百整除的年份,或能被一百整除的同时也能被四百整除的年份是闰年。

		if (year % 4 == 0 && year % 100 != 0|| year % 100 == 0 && year % 400 == 0)printf("闰年\n");
		else printf("不是闰年\n");

%为第三优先级,!=和==是第七优先级,&&是第十一优先级,||是第十二优先级,结合方向都为自左向右,判断条件没有问题可正常执行。

辗转相除法(欧几里得算法)求最大公约数

定理:

两个整数的最大公约数等于其中较小的那个数和两数相除余数的最大公约数。

	int n,m,temp;
	scanf("%d %d", &n,&m);
	if (n < m)//让最大的当除数
	{
		temp = n;
		n = m;
		m = temp;
	}
	while (m != 0)//当余数不为0时
	{
		temp = n % m;//计算出余数
		n = m;//被除数的值变为除数的位置上的值
		m = temp;//让余数的值变为被除数位置上的值
	}
	printf("%d",n);

相当于一条n%m=temp的式子,当temp不为0时数值都向左移,原本的除数不要,然后腾出余数的位置。
·最小公倍数等于n*m/最大公约数

计算从1到n的阶乘

递归法

基线(边界)条件:num>1。递归公式:add(num-1) * num。

long long add(int num)
{
	if (num > 1) return add(num-1) * num;
	else return 1;
}
int main()
{
	int num;
	long long result;
	scanf("%d", &num);
	result = add(num);
	printf("%lld", result);
}

循环法

	int num;
	long long result=1;
	scanf("%d", &num);
	for (int i = 1; i <= num; i++)
	{
		result *= i;
	}
	printf("%lld", result);
}

静态变量法

静态变量只定义一次,函数调用结束后值保留,且生存期为从程序开始到程序结束。

long long add(int num)
{
	static long long result = 1;
	if (num > 1)
	{
		result *= num;
		num--;
		add(num);
	}
	else return result;
}
int main()
{
	int num;
	scanf("%d", &num);
	printf("%lld", add(num));
}

计算从1到n的阶乘之和

递归法

long long add(int num)
{
	if (num > 1) return add(num - 1) * num;
	else return 1;
}
long long sum(int num)
{
	long long result = 0;
	for (int i = 1; i <= num; i++)result += add(i);
	return result;
}
int main()
{
	int num;
	scanf("%d", &num);
	printf("%lld", sum(num));
}

循环法

	int num;
	long long result = 0,multi=1;
	scanf("%d", &num);
	for (int i = 1; i <= num; i++)
	{
		multi *= i;
		result += multi;
	}
	printf("%lld", result);

用*画菱形

主要是举个例子介绍利用绝对值减少代码行数。

	for (int k = 3;abs(k)<=3;k--)
	{
		for (int j = abs(k); j >0; j--)printf(" ");
		for (int i = 7; i> 2*abs(k); i--)printf("*");
		printf("\n");
	}

利用数组判断素数

不采用遍历判断该数前的所有数来判断是否是素数。

	int a[100],i;
	for ( i = 1; i <= 100; i++)a[i] = i;
	a[1] = 0;
	for (i = 2; i < sqrt(100); i++)
	{
		for (int j = i + 1; j <= 100; j++)
		{
			if (a[i] != 0 && a[j] != 0)//若为0则已经被证实是非素数不需理会,不为0要么是素数要么还没判断
			{
				if (a[j] % a[i] == 0)a[j] = 0;//证实为非素数令其倍数为0
			}
		}
	}

选择排序

思想:每次都把序列中未排序的一个作为最值,第一个元素后的每个元素都和最值比较,符合条件则调换位置并刷新最值。

	int a[5] = { 5,2,7,3,8 },max;
	for (int i = 0; i < 5; i++)
	{
		max = a[i];
		for (int j = i + 1; j < 5; j++)
		{
			if (max < a[j])
			{
				int temp;
				max = a[j];
				temp = a[j];
				a[j] = a[i];
				a[i] = temp;
			}
		}
	}

n*n魔方阵

魔方阵排列规律:
·1放在第一行中间一列。
·从2开始直到n*n,每个数都比前一个数行数-1,列数+1。
·若上一个数行数为1,则下一个数行数为n,列数为上一个数列数+1。
·若上一个数列数为n,则下一个数列数为1,行数为上一个数行数-1。
·若按上述规则确定的位置上有数或上一个数是第一行第n列,则把下一个数放在上一个数的下面一行且同列。

	int square[15][15], i, j, k, p=1, n;
	while (p == 1)
	{
		scanf("%d", &n);
		if (n > 0 && n <= 15 && n % 2 != 0)
		{
			for (i = 1; i <= n; i++)
			{
				for (j = 1; j <= n; j++) square[i][j] = 0;//初始化
			}
			j = n / 2 + 1;//中间列
			i = 1;
			square[1][j] = 1;
			for (k = 2; k <= n * n; k++)
			{
				i--; j++;//由第二条规则可得下一个数的基本规则
				if (i<1 && j>n)//上一个数为第一行第n列时
				{
					i += 2;//因为每一次我们都是移动到下一个数的常规位置再开始判断的所以行数比之前多减-1,而要去到上一个数的下一行则要+2
					j -= 1;
				}
				else
				{
					if (i < 1)i = n;
					if (j > n)j = 1;
				}
				if (square[i][j] == 0)square[i][j] = k;
				else//与上面同理
				{
					i += 2;
					j -= 1;
					square[i][j] = k;
				}
			}
			for (i = 1; i <= n; i++)//输出魔方阵
			{
				for (j = 1; j <= n; j++)printf("%d ", square[i][j]);
				printf("\n");
			}
		}
		else p = 0;
	}

二分查找法/折半查找法

使用条件:列表是有序的。
思想:每次都检查中间元素知道搜索区间为空时结束查找。
例题:有15个从大到小顺序排列的数存放在数组中,输入一个数,输出其排在第几位。

#define N 15
int main()
{
	int n;
	int left=0, right=N-1,mid,judge=0;
	int num[N] = { 1,3,6,8,11,14,19,20,22,34,35,44,45,67,70 };
	scanf("%d", &n);
	while (left <= right)
	{
		mid = (left + right) / 2;//每次取中间值比较
		if (num[mid] != n)
		{
			if (num[mid] > n)right = mid-1;//中间数比目标大则右边界为mid-1
			else left = mid+1;//小则左边界为mid+1
		}//因为mid已经检查过所以边界可不包含mid
		else
		{
			judge = 1;
			printf("%d", mid + 1);//因为没有第0个的说法所以改成+1的形式
			break;
		}
	}
	if (judge == 0)printf("not found");
}

注意:判断边界时的条件不可以是left<right,因为当left==right时这个数还没经过判断。

二维数组行列互换

核心代码:

temp=array[i][j];
array[i][j]=array[j][i];
array[j][i]=temp;

冒泡排序

思想:相邻两个数比较,符合条件则交换位置。
缺点:有可能在排序好后还会继续进行比较,会耗费时间。

#define N 12
int main()
{
	int array[N] = { 11,3,5,1,7,-7,4,9,-6,8,10,4 };
	for (int i = 0; i < N-1; i++)//N个元素只需要跑N-1遍,最后一个数之后已经没有数可以比较了
	{
		for (int j = 0; j < N - i-1; j++)//每循环一次一个最值便排前面,之后的比较可以不考虑它
		{
			if (array[j + 1] > array[j])
			{
				int temp;
				temp = array[j + 1];
				array[j + 1] = array[j];
				array[j] = temp;
			}
		}
	}
}

进制转换(十六进制转十进制)

此处先默认输入的数字符合十六进制规范。

	char c;
	int n=0;	
	c = getchar();
	while (c!= '\n')
	{
		if (c >= '0' && c <= '9')n = n * 16 + c - '0';
		else if (c >= 'a' && c <= 'f')n = n * 16 + c - 'a';
		else if (c >= 'A' && c <= 'F')n = n * 16 + c - 'A';
		c = getchar();
	}
	printf("%d", n);

由于此方法从最高位开始计算所以才需要每次都让原来的n乘上16,最高位数字应为16的(位数-1)次方。

调换数字

题目:输入10个整数,先将其中最小的数与第一个数调换,再将最大的数与最后一个数调换。(使用指针法)

·此题要注意如果最大值为第一个数时,经过最小值与第一个数调换后,此时最小值的指针指向的值为最大值,最大值的指针指向的值为最小值。若要进行最大的数与最后一个数调换必须先把此时min指针的地址给max。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值