头歌C语言实验 辅助练习6:循环结构 II

第1关:数列求和

问题描述

对于用户从键盘输入的正整数a和n,编程计算s = a + aa + aaa + aaaa + aa…a(n个a)的值。 例如: 当a = 2,n = 5时,需要计算5个由2构成的整数的和:2 + 22 + 222 + 2222 + 22222。 若用户输入:5 3,则表示需要把3个由5构成的整数相加,即计算5 + 55 + 555的和,此时应该输出:615。 若用户输入:5 4,则表示需要计算5 + 55 + 555 + 5555的和,应该输出:6170。

输入

两个用一个空格分开的正整数a和n,输入数据保证a和n的值都小于9。

输出

一个正整数,即累加求和的结果。

输入示例

5 3

输出示例

615

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>

int main() {
int a, n, i, j;
int s = 0, t = 0;
scanf("%d %d", &a, &n);
for (i = 0; i < n; i++) {
t = t * 10 + a;
s += t;
}
printf("%d", s);
return 0;
}

第2关:几位数

问题描述

对于用户输入的一个非负整数n,请使用循环编程判断n是一个几位整数。 **注意:**0是1位数。

输入

一个任意的非负整数n,测试数据输入的n不会超过unsigned int所能表示的最大值(4294967295)。

输出

参照示例按照“非负整数y是一个x位整数。”的格式输出判断结果,其中y和x要用实际数值代替。

输入示例

8482

输出示例

非负整数8482是一个4位整数。

提示

对于任意整数,如果用它整除10可以去掉其个位数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

int main() {
unsigned int number;
unsigned int originalNumber;
int digitCount;

scanf("%u", &number);
originalNumber = number;
digitCount = 1;
while (number >= 10) {
number /= 10;
digitCount++;
}
printf("非负整数%d是一个%d位整数。\n", originalNumber, digitCount);
return 0;
}

第3关:啤酒节

问题描述

一年一度的啤酒节又到了,这是一个值得欢庆的日子,各大啤酒厂商为了推广自己的啤酒品牌,纷纷开展了啤酒促销活动。某啤酒厂商的促销活动是这样的:针对购买该品牌啤酒的顾客,每两个空酒瓶能换一瓶啤酒,每四个瓶盖也能换一瓶啤酒。 例如,如果某个顾客最初购买了该品牌的3瓶啤酒,那么他的兑换过程如下:

  1. 他喝完以后有3个空酒瓶和3个瓶盖,拿其中2个空酒瓶可以兑换1瓶啤酒,将这瓶啤酒喝完后,顾客现在还有3 - 2 + 1 = 2个空酒瓶和3 + 1 = 4个瓶盖;
  2. 那么现在手里的空酒瓶和瓶盖又可以兑换2瓶啤酒(2个空酒瓶和4个瓶盖兑换的);
  3. 喝完第二次兑换的两瓶啤酒后,顾客此时有2个空酒瓶和2个瓶盖,可以继续拿2个空酒瓶兑换1瓶啤酒;
  4. 继续喝完第三次兑换的一瓶啤酒,现在顾客有1个空酒瓶和3个瓶盖,不能再继续兑换了。所以顾客最多可以喝到3 + 1 + 2 + 1 = 7瓶啤酒。

假定某位顾客最初购买了n瓶该品牌的啤酒,聪明的你能帮他算一算他最多能喝到多少瓶啤酒吗?

输入

输入只有一个正整数n,表示顾客最初购买的啤酒瓶数。

输出

参照示例该顾客最多能够喝到的啤酒瓶数。

输入示例

4

输出示例

最多能喝到11瓶啤酒

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int main() {
int n, total = 0, bottles = 0, caps = 0;
scanf("%d", &n);
total = bottles = n;
caps = n;

while (bottles >= 2 || caps >= 4) {
int new_bottles = bottles / 2 + caps / 4;
total += new_bottles;
bottles = bottles % 2 + new_bottles;
caps = caps % 4 + new_bottles;
}

printf("最多能喝到%d瓶啤酒\n", total);
return 0;
}

第4关:统计字符数

问题描述

输入一行字符,分别统计出其中英文字母、数字、空格和其他字符的个数。

输入

输入只有一行,其中包含若干个任意字符。

输出

输出包括4行: 第一行输出其中的英文字母个数; 第二行输出其中的数字字符个数; 第三行输出其中的空格字符个数; 第四行输出其中的其它字符个数。

输入示例

I am a student, I am 20 years old.

输出示例

字母字符:22 数字字符:2 空格字符:8 其它字符:2

提示

当用户输入完一行字符并按下回车键后,所有字符包括最后的回车键产生的换行符(‘\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
#include <stdio.h>
#include <ctype.h>

int main() {
char c;
int letters = 0, digits = 0, spaces = 0, others = 0;

while ((c = getchar()) != '\n' && c != EOF) {
if (isalpha(c)) {
letters++;
} else if (isdigit(c)) {
digits++;
} else if (isspace(c)) {
spaces++;
} else {
others++;
}
}

printf("字母字符:%d\n", letters);
printf("数字字符:%d\n", digits);
printf("空格字符:%d\n", spaces);
printf("其它字符:%d\n", others);

return 0;
}

第5关:计算圆周率 II

问题描述

众所周知,可以使用级数展开公式近似计算圆周率π,下面的这个公式可以算是其中最简单的一个: π/4=1-1/3+1/5-1/7+1/9-… 请编写程序根据上述公式近似计算圆周率π的值,要求一直计算直到某个求和项的绝对值小于m时为止。m的值由用户从键盘输入,例如1e-6,1e-10等。

输入

一个浮点数m。

输出

一个浮点数,表示圆周率π的近似值,精确到小数点后8位。

输入示例

1e-4

输出示例

3.14139265

提示

为保证数据精度准确无误,涉及到实数的变量请使用double类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <math.h>

int main() {
double m, piover4 = 0.0, term = 1.0;
int i = 0;
scanf("%lf", &m);

while (fabs(term) > m) {
piover4 += term;
i++;
term = pow(-1, i) / (2 * i + 1);
}

printf("%.8f\n", piover4 * 4);
return 0;
}

第6关:打印质数

问题描述

质数是不能被1和它本身以外的其它整数整除的正整数,按照这个定义,负数、0和1都不是素数。 请编写一段程序,对于用户输入的两个任意的整数a和b,在屏幕上打印出a和b之间的所有质数。

输入

两个用空格分开的任意整数a和b。

输出

输出a和b之间的所有质数。 输出可能包含多行,每行最多输出5个质数,输出每个质数时指定宽度为5,并且按右对齐的方式输出,不要输出多余的空格。

输入示例

3 40

输出示例

3 5 7 11 13 17 19 23 29 31 37

提示

注意a和b都可以是任意的整数(负数、0和正数),并且a和b的大小关系也是不确定的。

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>
#include <stdbool.h>

bool is_prime(int n) {
int i;
if (n <= 1) return false;
for (i = 2; i * i <= n; i++) {
if (n % i == 0) return false;
}
return true;
}

int main() {
int a, b, start, end, i, count;
count = 0;

scanf("%d %d", &a, &b);
if (a > b) {
start = b > 2 ? b : 2;
end = a;
} else {
start = a > 2 ? a : 2;
end = b;
}

for (i = start; i <= end; i++) {
if (is_prime(i)) {
printf("%5d", i);
count++;
if (count % 5 == 0) {
printf("\n");
}
}
}

if (count % 5 != 0) {
printf("\n");
}
return 0;
}