C语言作业(二)
Wucheng

作业


阶乘表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
int main(void)
{
int factorial = 1;

printf("n \t n的阶乘\n");
for (size_t i = 1; i <= 10; i++) //打印10行
{
for (size_t x = 1; x <= i; x++) //阶乘
{
factorial *= x;
}

printf("%d! \t %d\n",i,factorial);
factorial = 1;

}

}


满足条件的平方数

条件:四位数,第一位数和第三位数的和为10,第二位和第四位积为12

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
int main(void)
{
int num;
int part[4] = {0};

for (size_t i = 10; i < 100; i++)
{
num = i * i; //获得一个平方数
if (num > 9999) break; //超出四位数退出

for (int x = 3; x >= 0; x--)
{
part[x] = num % 10; //数组存储平方数每个数字
num /= 10;
}

if(part[0] + part[2] == 10 && part[1] * part[3] == 12) //条件判断
printf("%d%d%d%d 满足条件\n",part[0],part[1],part[2],part[3]);

}

}


1000以内的同构数

同构数:一个数的平方数的右边为其本身的数
例如:5^2=25,5则为同构数,25^2=625,25为同构数


方法1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
int main(void)
{
int num,part,part_reverse;
/*part用于存放平方数的最后几位数
由于%运算符获取到的数字为反方向
因此定义一个part_reverse来放相反的数*/
long num_square; //变量存放平方数


for (num = 1; num <= 1000; num++) //循环1000次
{
num_square = num * num;

part_reverse = 0; //每次循环初始化part_reverse的值
for (size_t i = 0; i < num_size(num); i++) //获取同构数的反向
{
part_reverse = part_reverse*10 + num_square % 10;
num_square /=10;
}

part = 0; //初始化part的值
while (part_reverse) //将数字变回正序
{
part = part * 10 + part_reverse % 10;
part_reverse /= 10;
}

if(part == num) printf("%d是同构数\n",num);

}

}

int num_size(int x)//获取数字的位数
{
int size = 0;

while (x > 0)
{
x /= 10;
size++;
}

return size;
}

方法2:

方法2相对于方法1简单粗暴许多,由于题目给出的条件是1000以内,那么我们就能先获取数字的位数然后switch来选择是%10还是%100

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>
int main(void)
{
int num,part;
long num_square;

for (num = 1; num <= 1000; num++)
{
num_square = num * num; //平方数

switch (num_size(num)) //获取平方数靠右的数字
{
case 1: part = num_square % 10;
break;
case 2: part = num_square % 100;
break;
case 3: part = num_square % 1000;
break;
case 4: part = num_square % 10000;
break;
}

if (num == part) printf("%d是同构数\n",num);

}

}

int num_size(int x)//获取数字的个数
{
int size = 0;

while (x > 0)
{
x /= 10;
size++;
}

return size;
}

小结

方法1判断的不仅仅可以是1000以内,也能判断更大的数,方法2则需要多加几条case。

不过很显而易见的,方法2更加通俗易懂,简单粗暴。

(方法1如果用数组写起来更加的方便易懂,但是我就是想用一下在之前的获取相反数字的题目中用到的计算方法)



计算成绩平均数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
int main(void)
{
float grade,num,sum;
num = 0, sum = 0;

printf("求学生成绩平均数,请输入第一个学生成绩(输入“#”退出):");
while (scanf("%d",&grade) == 1)
{
printf("录入成功,请输入下一个学生的成绩:");
sum += grade;
num++;
}

printf("学生成绩的平均数为%.2f",sum/num);

}

实际上这题还是很简单的,不过

while (scanf(“%f”,&grade) == 1)

这里的 while用法是在书上看到的特别记录一下。
如果 scanf函数获成功得到了一个正确的类型值,那么就会有一个返回值 1
如果 scanf函数中有两个 %d并且都获取到了正确的类型,那么就会返回一个 2
在这里 while循环就用 scanf的返回值来进行判断是否进入循环



输出数组

要求:输入若干个数,以 -1为条件结束,以每3个数为一行输出,并且将积数放入另一个数组输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
int main(void)
{
int num[30][3] = {0};
int n,product[90] = {0};
n = 0; //积数数组的下标变量

printf("请输入10个以上的整数(输入-1停止):");
for (size_t i = 0; i < 30; i++)
{
for (size_t x = 0; x < 3; x++)
{
scanf("%d",&num[i][x]);
if(num[i][x] == -1) goto out;
}

}
out:

printf("\n");
for (size_t i = 0; i < 30; i++)
{
for (size_t x = 0; x < 3; x++)
{
if(num[i][x] == -1) goto put;
printf("%d\t",num[i][x]);
if(num[i][x] % 2 ==1) //积数判断
{
product[n] = num[i][x];
n++;
}
}
printf("\n");
}
put:

printf("\n输入的积数有:");
for (size_t i = 0; i < n; i++)
{
printf("%d ",product[i]);
}

}


杨辉三角

这个题目有两种思路,一种是用杨辉三角形的规律——三角中间的数为上方两个数字的和,用二维数组进行处理。

另一种解法就是高中所学的二项式定理,杨辉三角满足二项式系数的规律,因此可以设置循环来输出杨辉三角。


二项式解法

首先我们先来看一下杨辉三角的二项式系数规律(阶乘表示)

1
2
3
4
5
n=0     1
n=1 1 1!/1!
n=2 1 2!-1!/1! 2!/2!
n=3 1 3!-2!/1! 3!-1!/2! 3!/3
……

然后再加入横列加入标号看看规律

1
2
3
4
5
6
        x=0     x=1         x=2        x=3
n=0 1
n=1 1 1!/1!
n=2 1 2!-1!/1! 2!/2!
n=3 1 3!-2!/1! 3!-1!/2! 3!/3
……

最后把阶乘变成乘法表示

1
2
3
4
5
6
        x=0    x=1        x=2           x=3             x=4
n=0 1
n=1 1 1/1
n=2 1 2/1 2*1/2*1
n=3 1 3/1 3*2/2*1 3*2*1/3*2*1
n=4 1 4/1 4*3/2*1 4*3*2/3*2*1 4*3*2*1/4*3*2*1

看规律可以得知x的值为分子的阶乘,也为分母阶乘的次数终止(x=0时不循环,1为本身,2为阶乘两次终止)

理解规律后就可以按思路完成,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
int main(void)
{
int num_up,num_down; //用于分子和分母(不会这两个单词,懒得翻译)

for (size_t n = 0; n < 9; n++) //打印9层
{
for (size_t x = 0; x <= n; x++) //可以将n,x与上方相对应理解
{
num_up = 1;
num_down = 1; //每次循环初始化分子分母的值

for (size_t i = n, f = x; f > 0; f--, i--) //n的值不能动,用i值代替。x值也不能动,用f替换完成分子循环次数
num_up *= i;

for (size_t i = x; i > 0; i--) //分子的阶乘
num_down *= i;

printf("%-2d ",num_up / num_down); //相除得出相应表中的数值
}
printf("\n");
}

}

杨辉三角性质解法

我们可以对三角形进行观察

1
2
3
4
5
6
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
……

观察三角形的规律,三角形的两边都是1,三角新内部的数字则是上方的数字与左上的数字之和
那么我们就可以建立一个n*n的数组再用把数组的数字按规律赋值再输出即可

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<stdio.h>
#define NUMBER 10
int main(void)
{
int x[10][10] = {0};

for (size_t i = 0; i < NUMBER; i++)//初始化杨辉三角形两边
{
x[i][0] = 1;
x[i][i] = 1;
}

for (size_t i = 0; i < NUMBER; i++)//对三角内部赋值
{
for (size_t t = 0; t <= i; t++)
{
if(x[i][t] == 1) continue;
x[i][t] = x[i-1][t] + x[i-1][t-1];
}
}

for (size_t i = 0; i < NUMBER; i++)
{
for (size_t t = 0; t <= i; t++)
printf("%-5d",x[i][t]);

printf("\n");
}
}