20201022-成信大-C语言程序设计-20201学期《C语言程序设计B》C-trainingExercises11
P211
/*
编写一程序P211.C实现以下功能
根据输入的n在屏幕上显示对应的以#组成的菱形图案。
编程可用素材:
printf("Please input n: ");
程序的运行效果应类似地如图1和图2所示,图1中的1和图2中的5是从键盘输入的内容。
Please input n: 1
#
###
#
图1 程序运行效果示例(n=1时)
Please input n: 5
#
###
#####
#######
#########
###########
#########
#######
#####
###
#
*/
#include <stdio.h>
/*
函数声明
*/
void printfBlank(int n);
void printfDiamond(int n);
int main(void)
{
int data, i;
printf("Please input n: ");
scanf("%d", &data);
// 上三角
for (i = 0; i <= data; i++)
{
// 打印空格
printfBlank(data - i);
// 打印#号
printfDiamond(i * 2 + 1);
// 打印回车
printf("\n");
}
// 下三角
for (i = data ; i > 0; i--)
{
// 打印空格
printfBlank(data - i + 1); // 从一个空格开始打印
// 打印#号
printfDiamond(i * 2 - 1); // 从2*data-1个开始打印#
// 打印回车
printf("\n");
}
return 0;
}
/*
函数实现
用的于输出n个空格
*/
void printfBlank(int n)
{
int i;
for (i = 0; i < n; i++)
{
printf(" ");
}
}
/*
函数实现
用于输出n个#
*/
void printfDiamond(int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("#");
}
}
另一种思路,见代码如下
#include <stdio.h>
/*
这个程序,算法上还没有完全想清楚
1. 可以一行一行地分析
2. 可以"%*.*s"来输出,但s串要足够长
2.1 第一个*即位宽,第二个*即输出字符个数,【位宽-字符数,即前面补充的空格数】
2.2 转化为对整个一行【宽度】的控制,以及【#数】的控制,相减即为之前的【空格】补位的数量
2.3 整个一行,仍然由三个部分构成:【空格+#+回车】
*/
int main(int argc,char *argv[])
{
int i,n;
const char *s = "########################################";
printf("Please input n: ");
scanf("%d", &n);
// 上三角
for ( i = 1; i <= n+1; i++)
{
printf("%*.*s\n", n+i,2*i-1, s);
}
// 下三角
for ( i = n; i >=1 ; i--)
{
printf("%*.*s\n", n+i,2*i-1, s);
}
return 0;
}
这个思路要更简单一些,但要求大家对printf格式化输出里的
%*.*s
要有深入的理解。
P212
/*
编写一程序P212.C实现以下功能
根据输入的n(约定n>1)在屏幕上显示对应的图案。
编程可用素材:
printf("Please input n: ");
程序的运行效果应类似地如图1和图2所示,图1中的2和图2中的5是从键盘输入的内容。
Please input n: 2
a
b b
a
图1 程序运行效果示例(n=2时)
Please input n: 5
a
b b
c c
d d
e e
d d
c c
b b
a
图2 程序运行效果示例(n=5时)
分析
1 任意一行:若干空格 + 一个字母 + 若干空格 + 一个字母 + 回车
2 字符随行的变化而自增
3 前部空格,上三角是减少,下三角是增加
4 中间空格,上三角是增加,下三角是减少
*/
#include <stdio.h>
void printfBlank(int n);
void printfAlpha(int n);
int main(void)
{
int n;
int i;
printf("Please input n: ");
scanf("%d", &n);
// 上三角
for (i = 0; i < n;i++)
{
printfBlank(n - i - 1);
printfAlpha(i);
printfBlank(2 * i - 1);
if(i==0)
{
}
else
{
printfAlpha(i);
}
printf("\n");
}
// 下三角
for (i = n - 2; i >= 0; i--)
{
printfBlank(n - i - 1);
printfAlpha(i);
printfBlank(2 * i - 1);
if(i==0)
{
}
else
{
printfAlpha(i);
}
printf("\n");
}
return 0;
}
/*
输出n个空格
*/
void printfBlank(int n)
{
int i;
for (i = 0; i < n; i++)
{
printf(" ");
}
}
/*
打印字母
如果n从0开始,即输出从97开始的字符,也就是abcde...
*/
void printfAlpha(int n)
{
printf("%c", n + 97);
}
P213
/*
编写一程序P213.C实现以下功能
根据输入的n(约定n>0)在屏幕上显示对应的图案。
编程可用素材:
printf("Please input n: ");
程序的运行效果应类似地如图1和图2所示,图1中的3和图2中的5是从键盘输入的内容。
Please input n: 3
@ @
@ @
@
@ @
@ @
图1 程序运行效果示例(n=3时)
Please input n: 5
@ @
@ @
@ @
@ @
@
@ @
@ @
@ @
@ @
图2 程序运行效果示例(n=5时)
@ @
@ @
@ @
@ @
@
@ @
@ @
@ @
@ @
分析
1 任意一行:若干空格 + 一个字母 + 若干空格 + 一个字母 + 回车
2 字符随行的变化而自增
3 前部空格,上三角是增加,下三角是减少
4 中间空格,上三角是减少,下三角是增加
具体实现时,将中间行放在上三角处理
*/
#include <stdio.h>
void printfBlank(int n);
void printfAlpha(char c);
int main(void)
{
int n;
int i;
printf("Please input n: ");
scanf("%d", &n);
// 上三角
for (i = 0; i < n; i++)
{
// 前面的空格 0 1 2 3 4
printfBlank(i);
// 首字母
printfAlpha('@');
// 中间空格 7 5 3 1 0
printfBlank((n - i) * 2 - 3);
// 尾字母
if((n - i) * 2 - 3 <= 0)
{}
else
{
printfAlpha('@');
}
// 回车
printf("\n");
}
// 下三角
for (i = 0; i < n -1; i++)
{
// 前面的空格 3 2 1 0
printfBlank(n - i -2);
// 首字母
printfAlpha('@');
// 中间空格 1 3 5 7
printfBlank(i * 2 + 1);
// 尾字母
printfAlpha('@');
// 回车
printf("\n");
}
return 0;
}
/*
打印空格
*/
void printfBlank(int n)
{
int i;
for (i = 0; i < n; i++)
{
printf(" ");
}
}
/*
打印字符
*/
void printfAlpha(char c)
{
printf("%c", c);
}
P214
/*
编写一程序P214.C实现以下功能
根据输入的n(约定n>0)在屏幕上显示对应的图案。
编程可用素材:
printf("Please input n: ");
程序的运行效果应类似地如图1和图2所示,图1中的3和图2中的5是从键盘输入的内容。
Please input n: 3
$ $
$$
$
$$
$ $
图1 程序运行效果示例(n=3时)
Please input n: 5
$ $
$ $
$ $
$$
$
$$
$ $
$ $
$ $
图2 程序运行效果示例(n=5时)
分析
1. 单行分析
2. 行分析
3. 区别三:上三角,中行,下三角
*/
#include <stdio.h>
void printfBlank(int n); // 打印n个空格
void printfAlpha(char c); // 打印指字字符
int main(void)
{
int n;
int i;
printf("Please input n: ");
scanf("%d", &n);
// 上三角
for (i = 0; i < n;i++)
{
// 行首字符
printfAlpha('$');
// 中间的空格 3 2 1 0
printfBlank(n - 2 - i);
// 行尾字符
if( n - 2 - i < 0)
{}
else
{
printfAlpha('$');
}
// 回车换行
printf("\n");
}
// // 中间行
// printfAlpha('$');
// 下三角
for (i = 0; i < n - 1;i++)
{
// 行首字符
printfAlpha('$');
// 中间的空格 0 1 2 3
printfBlank(i);
// 行尾字符
printfAlpha('$');
// 回车换行
printf("\n");
}
return 0;
}
void printfBlank(int n)
{
int i;
for (i = 0; i < n; i++)
{
printf(" ");
}
}
void printfAlpha(char c)
{
printf("%c", c);
}
P731
/*
编写一程序P731.C实现以下功能
输出n行星号,每行5个*星号。
编程可用素材:
printf("please input n: ");
程序的运行效果应类似地如图1所示,图1中的4是从键盘输入的内容。
please input n: 4
* * * * *
* * * * *
* * * * *
* * * * *
图1 程序运行效果示例
*/
#include <stdio.h>
int main(void)
{
int n, i;
printf("please input n: ");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("\n* * * * *"); // 每行5个星号硬输出
}
return 0;
}
P830
/*
编写一程序P830.C实现以下功能
求1+2+3+……+n≤m时的最大n值及和sum(=1+2+3+……+n),其中m从键盘输入——不得使用解方程、算平方根方法。
编程可用素材:
printf("please input m: ");
printf("\nResult: n=…, sum=…);
程序的运行效果应类似地如图1所示,图1中的10000是从键盘输入的内容。
please input m: 10000
Result: n=140, sum=9870
图1 程序运行效果示例
*/
#include <stdio.h>
int main(void)
{
int n,sum = 0;
int m;
int i;
printf("please input m: ");
scanf("%d", &m);
for (i = 0;;i++)
{
sum += i;
if(sum > m)
{
n = i - 1; // 找到需要的n
sum = sum - i; // 计算需要的sum
break; // 结束增长测试
}
}
printf("\nResult: n=%d, sum=%d",n,sum);
return 0;
}
P215
/*
编写一程序P215.C实现以下功能
求S=1/1!+1/2!+1/3!+…+1/N!并输出结果(显示时小数部分占16位,计算时要求从第1项开始往后累加)。
N为任意自然数(只考虑int型),从键盘读入。
编程可用素材:
printf("Please input n: ");
printf("\nS=1/1!+1/2!+...+1/…!=…);
程序的运行效果应类似地如图1所示,图1中的18是从键盘输入的内容。
Please input n: 18
S=1/1!+1/2!+...+1/18!=1.7182818284590455
图1 程序运行效果示例
*/
#include <stdio.h>
double getFact(int n);
int main(void)
{
int n, i;
double result = 0;
double fact = 1.0;
printf("Please input n: ");
scanf("%d", &n);
for (i = 1; i <= n; i++)
{
result += 1.0/getFact(i);
}
printf("\nS=1/1!+1/2!+...+1/%d!=%18.16lf", n, result);
return 0;
}
double getFact(int n){
int i;
double result = 1.0;
for (i = 1; i <= n; i++)
{
result *= i;
}
return result;
}
P745
/*
编写一程序P745.C实现以下功能
输入两个正整数m和n,求其最大公约数和最小公倍数。注:
最大公约数也称最大公因子,指某几个整数共有因子中最大的一个;
两个整数公有的倍数称为它们的公倍数,其中最小的一个正整数称为它们两个的最小公倍数。
编程可用素材:
printf("please input two integer numbers: ");
printf("\nthe greatest common divisor is …);
printf("\nthe least common multiple is …);
程序的运行效果应类似地如图1所示,图1中的35 15是从键盘输入的内容。
please input two integer numbers: 35 15
the greatest common divisor is 5
the least common multiple is 105
图1 程序运行效果示例
*/
#include <stdio.h>
int getGcd(int m, int n);
int getLcm(int m, int n);
int main(void)
{
int m, n;
int gcd, lcm; // 最大公约,最小公倍
printf("please input two integer numbers: ");
scanf("%d %d", &m, &n);
gcd = getGcd(m, n);
lcm = getLcm(m, n);
printf("\nthe greatest common divisor is %d", gcd);
printf("\nthe least common multiple is %d", lcm);
return 0;
}
int getGcd(int m, int n)
{
int r;
// 保证 m > n;
if (m < n)
{
r = m;
m = n;
n = r;
}
// 辗转相除,取余数判断
r = m % n;
while (r != 0)
{
m = n; // 除数 ---> 被除数
n = r; // 余数 ---> 除数
r = m % n;
}
return n;
}
int getLcm(int m, int n)
{
return m * n / getGcd(m, n);
}
/*
辗转相除法(欧几里德算法)
算法步骤:
1. 输入两个正整数m, n(m>n)
2. 计算m除以n的余数r
3. m=n, n=r
4. 若r=0, 则m和n的最大公因数等于m;否则转到第2步
5. 输出最大公因数m,即gcd
因为:a x b = gcd(a, b) x lcm(a,b)
所以:lcm(a,b) = a x b / gcd(a, b)
*/