序言:在上次的尝试中,感觉还不错。相比与之前的学习,有了不错的提升。锻炼了自己的语言输出表达,以及对代码的理解。后续继续坚持,还有根据艾宾浩斯遗忘曲线,及时回顾。

  • 输出50个素数
#include <stdio.h>

/* 列举50个素数 */
int main()
{
   
	int i = 1;
	int count = 0;
	while (count < 50){
   
		int isPrime = 1;
		//scanf_s("%d", &num);
		//int num1 = num;
		for (int j = 2; j <= i / 2; j++){
   
			if (i % j == 0)
			{
   
				isPrime = 0;
				break;
			}
		}
		if (isPrime == 1){
   
			printf(" %d\t", i);
			count++;
			if (count % 5 == 0) {
      //每5个数换行 
				printf("\n");
			}
		}
		i++;
	}
}

总结:学会了两种程序检查方法,设置输出语句,及时查看那步数据有问题。设置统计变量。以及对原始数据的保护。设置标志值。以及输出格式,对每五个数字进行一个换行。

  • 凑硬币
#include <stdio.h>

/* 如何用 1角 2 角 5角 的前凑出所要的钱数(10元一下) */
int main()
{
   
	int money;  //表示用户所输入的钱数
	scanf_s("%d",&money); 
	int  one, two, five;//分别表示 1角 2 角 5角
	int flag = 0; //标志何时停止
	for ( one = 1; one < money*10 ; one++)
	{
   
		for ( two = 1; two < money*10/2; two++)
		{
   
			for ( five = 1; five < money*10/5; five++)
			{
   
				if(one + two*2 +five*5 == money*10)
				{
   
					flag = 1;
					printf("%d元可以由%d个一角和%d个二角以及%d个五角凑成\n",money,one,two,five);
					break;
				}
			}
			if (flag )
			{
   
				break;
			}
		}
		if (flag )
		{
   
			break;
		}
	}
}

总结:学习了一个新的名词,贪心算法,目前的理解,枚举,通过一个一个的列举。还学习到了两个结束循环的变量。break 结束整个循环,直接跳出。continue 结束本层循环,循环仍然继续。以及往后写程序的思路,先进行算法分析,模拟一下运算过程,根据运算过程写代码,感觉会来的更快一些,之前也没有尝试过。感觉之前自己学的没有什么实在的东西。学习完计算机后,自己真的很迷茫。代码啥的完全没有想法,遇见算法题完全没有思考步骤。总结下立自己根本没有形成一种做题思维,没有思考,总结。最重要的还是代码看的太少。有感而发,还是好好做吧。进入正题,对题目分析,凑钱数 ,枚举,贪心算法,最简单的思路,一个个列举,三种钱,三个fou循环,设置的先后顺序,以及对标志位的设置,初始数据的保护。
算法改进

#include <stdio.h>

/* 如何用 1角 2 角 5角 的前凑出所要的钱数(10元一下) */
int main()
{
   
	int money;  //表示用户所输入的钱数
	scanf_s("%d",&money); 
	int  one, two, five;//分别表示 1角 2 角 5角
	int flag = 0; //标志何时停止
	for ( one = 1; one < money*10 ; one++)
	{
   
		for ( two = 1; two < money*10/2; two++)
		{
   
			for ( five = 1; five < money*10/5; five++)
			{
   
				if(one + two*2 +five*5 == money*10)
				{
   
					flag = 1;
					printf("%d元可以由%d个一角和%d个二角以及%d个五角凑成\n",money,one,two,five);
					goto out;
				}
			}
			/*if (flag ) { break; }*/
		}
		/*if (flag ) { break; }*/
	}
	out:
	return 0;
}

总结:使用了goto语句,直接跳转到某条语句,方便多层循环的直接跳出。用法:goto xxx; xxx;

  • 交错(调和)级数求和
#include <stdio.h>

/* 前n项和 1 - 1/2 + 1/3 - 1/4 +......+1/n */
int main()
{
   
	int n;
	double sum=0.0;
	int sign = 1;
	scanf_s("%d", &n);
	for (int i = 1; i <= n; i++)
	{
   
		sum += sign*1.0 / i;
		sign = -sign;
	}
	printf("f(%d)=%f",n,sum);

}

总结:累加器 sum 以及标识符 一正一负的变换,
循环的设置,以及对数据类型的设置,题目较为简单,不过多的赘述。

  • 整数的拆解
#include <stdio.h>

/* 整数拆解 思路: 13425 / 10000 = 1 13425 % 10000 = 3425 10000 / 10 = 1000 3425 / 1000 = 3 3425 % 1000 = 425 ...... 核心思想 : % 求余 / 相除 */
int main()
{
   
	int mask = 1; //记录权值
	int  num;
	scanf_s("%d",&num);
	int t = num;//保存计算变量
	int count = 0;//记录输出值
	while ( t > 9)  //统计位数确定 权值
	{
   
		mask *= 10;
		t /= 10;
	}
	/*printf("mask=%d",mask);*/
	while ( mask > 0)
	{
   
		count = num / mask;
		printf("%d", count);
		if ( mask > 9) //小细节 最后一个没有空格
		{
   
			printf(" ");
		}
		num %= mask;
		mask /= 10;	
	}
}

总结:先写拆解过程,依次除以它相对应的mask位,实现拆,依次取余相对应的mask位,实现解。根据数位确定mask,依次从1累乘10,实现。

  • 求最大公约数
#include <stdio.h>

/* 辗转相除求最大公约数 a第一步运行之后 永远是较大的那个数 当 b 不等于零时 t = a % b a = b b = t a b t 12 18 12 18 12 6 12 6 0 6 0 */
int main()
{
   
	int a, b;
	int t = 0;
	scanf_s("%d %d",&a,&b);
	while ( b != 0)
	{
   
		t = a % b;
		a = b;
		b = t;
		printf("a=%d,b=%d,t=%d\n",a,b,t);
	}
	printf("最大公约数(gcd)为:%d",a);
	return 0;
}

总结:这里有一个重要思想,辗转相除法。很精妙,古人的智慧不可小觑,学习呀,从古传到今,必有它存在的价值,学会去领悟。发现写的写的,脑袋中总迸发出不一样的声音,貌似和写的此程序无关,但感觉可以增加写博客的乐趣,更加感觉到是在和人交流,而不是单纯的啦啦知识。回归,学会主流算法,可以很大的减少代码的长度,以及提高执行效率。a 永远装较大的数 最终的a位所求值。

  • 数的组合拼装
#include <stdio.h>

/* 给定不超过6的正整数A,考虑从A开始的连续的4个数字,请输出由它们组成的 无重复 数字的三位数 eg: 输入 2 输出 23 思想: 三层嵌套循环 */
int main()
{
   
	int num; 
	int count = 0; //记录每行数字的个数
	scanf_s("%d",&num); //用户输入数字
	for (int i = num; i <= num + 3; i++)
	{
   
		for (int j = num; j <= num + 3; j++)
		{
   
			for (int k = num; k <= num + 3; k++)
			{
   
				if (i != j && j != k && k!=i)
				{
   
					printf("%d%d%d",i,j,k);
					count++;
					if (count == 6)
					{
   
						printf("\n");
						count = 0;
					}
					else
					{
   
						printf(" ");
					}
				}
			}
		}
	}
}

总结: 三位数的组合联想到三层for循环,枚举法,一个一个依次寻找,暴力破解,对输出格式的考虑,没6个换行,否则一个空格。

  • 水仙花数
#include <stdio.h>

/* 水仙花数 N位正整数(N > 3),它的每个位上的数字的N次幂之和等于它本身。 eg: 153 = 1^3 + 3^3 + 5^3 思想: 三位数 从100-999 依次遍历 如何根据三位数 确定 100 如何将数字拆解 / % 分解变量之前先保存 记录每次 n次幂累之和 */
int main()
{
   
	int num; //用户输入的正整数 水仙花位数
	scanf_s("%d",&num);
	int first = 1; // 记录遍历左边界
	for (int i = 1; i < num; i++)
	{
   
		first *= 10;
	}
	/*printf("%d",first); */
	int j = first;  //保存初始值
	while (j < first*10) //确定右边界
	{
     
		int t = j;    //分解变量 提前记录 
		int sum = 0;     //记录每次n次幂的累加和
		do
		{
   
			int d = t % 10;   //记录最低位
			t /= 10;    //依次降位
			int p = d;  //计算n次幂
			int j = 1;
			while (j < num )
			{
   
				p *= d;
				j++;
			}
			sum += p;
		} while ( t > 0 );	
		if ( sum == j )
		{
   
			printf("%d\n",j);
		}
		j++;
	}
	return 0;
}

总结:这个是学到现在最难理解的一个程序,基本上是在刚看完代码之后的基础上写出来的,属于机械式的记忆,没有做到很好的理解。水仙花数,n位数,每个位数上的数字的n方和累加等于这个N位数。需要用到对数字的拆解,基本思想还是暴力破解,首先确定n位数的左右边界,需要有一个累加和,依次从低位向高位进行拆分,累加。