序言:在上次的尝试中,感觉还不错。相比与之前的学习,有了不错的提升。锻炼了自己的语言输出表达,以及对代码的理解。后续继续坚持,还有根据艾宾浩斯遗忘曲线,及时回顾。
- 输出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位数的左右边界,需要有一个累加和,依次从低位向高位进行拆分,累加。