跳转至

第四章 循环结构的程序设计

第一节 for语句

2016:【例4.1】for循环求和

提示

循环累加

代码
#include <bits/stdc++.h>

using namespace std;

int sum, n;

int main(){
    cin >> n;
    for (int i = 1; i <= n; i++) sum += i;

    cout << sum << '\n';
    return 0;
}

2017:【例4.2】输出偶数

提示

for 循环,结合 if 语句判断 i 是不是偶数

代码
#include<bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    for (int i = 1; i <= n; i++)
        if (i % 2 == 0) cout << i << ' ';

    return 0;
}

2018:【例4.3】输出奇偶数之和

 2017:【例4.2输出偶数 类似

2019:【例4.4】求阶乘

累加求和变成了累乘求积
道理一样

1059:求平均年龄

累加求和求平均数
求平均数的时候需要注意强制转换还有保留小数
printf("%.2lf", ...);

1060:均值

 1059求平均年龄 类似

1061:求整数的和与均值

 1060均值 类似

1062:最高的分数

打擂台

1063:最大跨度值

提示

这也是打擂台

但这次,我们要求出最大值,还有最小值

代码
#include <bits/stdc++.h>

using namespace std;

int maxn = -1;
int minn = 1001;

int main() {
    int n;
    cin >> n;

    while (n--) {
        int x;
        cin >> x;

        maxn = max(maxn, x);
        minn = min(minn, x);
    }

    cout << maxn - minn << endl;

    return 0;
}

1064:奥运奖牌计数

提示

这是满足条件的,累加求和

循环读入,刚开始可能不会操作

提示2
while (n--) {
    cin >> a >> b >> c;
    suma += a, sumb += b, sumc += c;
}

1065:奇数求和

提示

for 循环,从 l 枚举到 r,[l, r]

判断 i 是不是 奇数

累加求和

if (i % 2 == 1) ...
if (i % 2) ...        // 这样写,也是 ok 的
if (i & 2) ...        // 这样写,更是 ok 的

1066:满足条件的数累加

 1065奇数求和 类似

1067:整数的个数

 1065奇数求和 类似
这回是统计计数

1068:与指定数字相同的数的个数

 1067整数的个数 类似
统计计数

1069:乘方计算

提示

我们先理解一下,指数

\(a^b\),表示 b 个 a 相乘

提示2

注意开long long

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int a, n;
    cin >> a >> n;

    long long res = 1ll;
    while (n--) {
        res *= a;
    }

    printf("%lld\n", res);

    return 0;
}

1070:人口增长

提示

这是一个数学课本里一个统计的应用题

我们要先理解一下,百分数

\(1 \%\),表示 \(1 * 0.01\),即 \(0.01\)

\(0.1 \%\),表示 \(0.1 * 0.01\),即 \(0.001\)

每年0.1%的增长,那就是 1 * 1.001

1071:菲波那契数

提示

循环迭代

c = a + b;
a = b;
b = c;
代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    int a = 1, b = 1, c;

    if (n <= 2) {
        cout << 1 << endl;
        return 0;
    }

    for (int i = 3; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }

    cout << c << endl;

    return 0;
}
代码2
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    int a = 1, b = 1, c = 1;  // 在这里,对c进行初始化,就可以解决n<=2的情况

    for (int i = 3; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }

    cout << c << endl;

    return 0;
}

1072:鸡尾酒疗法

提示

首先,读题要多读几遍。这个题面,相对比较长,有点饶

重点看,输入数据的描述:第一行为鸡尾酒疗法的数据,其余各行为各种改进疗法的数据。

所以,对应的样例1,输入是5,第1行是原数据,剩余的4行为改进数据。

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int T;
    cin >> T;

    int n, m;
    cin >> n >> m;

    double jiwei = m * 1.0 / n;
    for (int i = 1; i < T; i++) {
        cin >> n >> m;
        double newjiwei = m * 1.0 / n;

        if (newjiwei - jiwei > 0.05) cout << "better" << endl;
        else if (jiwei - newjiwei > 0.05) cout << "worse" << endl;
        else cout << "same" << endl;
    }

    return 0;
}

1073:救援

提示

这个题目,稍有难度,难度在读题上,这是一个应用题的题面

还有对直角坐标系的认识

已知点的坐标,求距离原点的距离,就是求线段的长度,用到了勾股定理

给你一个点,路程,使用勾股定理求解(勾股定理,知道吗?不知道,百度一下)

求出斜边,就是路程,sqrt(a * a + b * b)

模拟,去+上人+回+下人

有几个点,就循环几次,每次输入屋顶的坐标

image-20251009204035427

提示2

注意阅读输入描述:

每一行上包含两个表示屋顶相对于大本营的平面坐标位置的实数

代码
#include <iostream>
#include <cmath>

using namespace std;

double ret;

int main(){
    int n;
    cin >> n;

    while (n--){
        double x, y;
        int z;

        cin >> x >> y >> z;

        ret += sqrt(x * x + y * y) * 2 / 50 + 1.5 * z;
    }

    cout << (int)ceil(ret) << '\n';

    return 0;
}

1074:津津的储蓄计划

提示

这题,也是应用题的题面

要先对两个样例,进行手动模拟

列这样的表格,我写一下表头,

月份,月初津津有多少钱,预算花多少,花完剩余多少,妈妈的钱数,月底津津有多少

1     300            290       10          0           10

2     310            230       80          0           80

把样例1,和样例2,都这样模拟一遍,在纸质草稿纸上,进行

然后再说写代码的事情

写代码就是for 循环,从1到12,表示月份。模拟每个月的执行过程

代码
#include <bits/stdc++.h>

using namespace std;

int jinjin, mama;
bool flag;

int main(){
    for (int i = 1; i <= 12; i++){
        int x;
        cin >> x;

        jinjin += 300;
        if (jinjin < x){
            cout << '-' << i << '\n';
            flag = true;
            break;
        }

        jinjin -= x;
        mama += jinjin / 100 * 100;
        jinjin %= 100;
    }

    if (!flag){
        cout << jinjin + mama * 1.2 << '\n';
    }

    return 0;
}

1075:药房管理

提示

应用题的题面

药品总量是m,有n个人

循环,判断当前这个人要拿的要是否够

如果不够,计数器++

如果够,更新m的数值(减去当前这个人拿的药)

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int m, n;
    cin >> m >> n;

    int cnt = 0;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;

        if (x > m) cnt++;
        else m -= x;
    }

    cout << cnt << endl;

    return 0;
}

1076:正常血压

提示

循环输入,每次输入两个数

判断是否满足正常血压的条件

如果满足,计数器++,打擂台

如果不满足,计数器清零

这题较难,放在最后做

代码
#include <iostream>

using namespace std;

int ret, cnt;

int main(){
    int n;
    cin >> n;

    while (n--){
        int a, b;
        cin >> a >> b;

        if (a >= 90 && a <= 140 && b >= 60 && b <= 90){
            cnt++;
            ret = max(ret, cnt);        
        }
        else{
            cnt = 0;
        }
    }

    cout << ret;

    return 0;
}

1077:统计满足条件的4位数

提示

这是数位拆分

因为已经给定了是四位数

循环n次,每次输入一个数x

个位是 i % 10

十位是 i / 10 % 10

百位是 i / 100 % 10

千位是 i / 1000

判断满足条件,cnt++

1078:求分数序列和

提示

这题,有一定难度

难度在于,看不懂那个数列

怎么才能让自己看懂呢? 在笔记本上,抄写一遍,就能看懂了

然后我们要尝试发现规律,是有规律的

计算每一项求和的时候

每一次
sum += 1.0 * q / p; 

并注意 q  p要进行迭代变化
代码
#include <iostream>

using namespace std;

int n;
double sum;

int main(){
    cin >> n;

    int q = 2, p = 1;
    for (int i = 1; i <= n; i++){
        sum += 1.0 * q / p;
        int t = p;
        p = q;
        q = q + t;
    }

    printf("%.4lf\n", sum);

    return 0;
}

1079:计算分数加减表达式的值

提示

首先是一个多项式,每一项都是一个分数

要注意 1/i 强制转换的问题(1.0 / i

通过观察还发现,每一项正负交替

我们可以通过判断i的奇偶性(i % 2),控制是 +=, 还是 -=

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    double sum = 0.0;
    for (int i = 1; i <= n; i++){
        if (i % 2 == 1) sum += 1.0 / i;
        else sum -= 1.0 / i;
    }

    printf("%.4lf\n", sum);

    return 0;
}

1080:余数相同问题

提示

这个题目,就是一个枚举,从小到大枚举

从多小?2

到多大?无限

for (int x = 2; ; x++) ...

这样就可以实现无限循环

当满足条件,写一个if语句

找到答案,输出

break 跳出循环

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int a, b, c;
    cin >> a >> b >> c;

    for (int x = 2; ; x++) {
        if (a % x == b % x && b % x == c % x) {
            cout << x;
            break;
        }
    }

    return 0;
}

1081:分苹果

提示

要认真读题

思考怎么分,才是总数最少

在看样例,输入是 8,怎么得到的 36(一定要用草稿纸

然后你就知道是什么了

代码
#include<bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    int sum = 0;
    for (int i = 1; i <= n; i++)
        sum += i;
    cout << sum;

    return 0;
}
代码2
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;

    cout << (1 + n) * n / 2 << '\n';

    return 0;
}

1082:求小数的某一位

这题较难放在后面做
提示

n 是 10000, 不能通过 printf("%.nlf", ...) 语句进行输出

本质上,要进行类似竖式除法的模拟

一位小数的一位小数的算

提示2

a * 10 / b 用 a 每次乘上 10,表示向右移动一位小数

a = a * 10 % b 这个是用来表示每次除完之后的余数

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int a, b, n;
    cin >> a >> b >> n;

    int ret;
    while (n--) {
        ret = a * 10 / b;
        a = a * 10 % b;
    }

    cout << ret << '\n';

    return 0;
}

1083:计算星期几

提示

我们要理解,指数

然后要理解,星期几是7天一循环的

所以,和 \(a^b\) 具体是几,没有关系

\(%7\) 的结果有没有关系

提示2

随时取模

周几的计算结果,之和 \(%7\) 有关,那么,我们只需要保留余数就可以了

幂次运算,很容易爆炸,开longlong也没用。

所以,一定要,随时取模

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int a, b;
    cin >> a >> b;

    int t = 1;
    for (int i = 0; i < b; i++) {
        t *= a;
        t %= 7;
    }

    if (t == 0) cout << "Sunday" << '\n';
    if (t == 1) cout << "Monday" << '\n';
    if (t == 2) cout << "Tuesday" << '\n';
    if (t == 3) cout << "Wednesday" << '\n';
    if (t == 4) cout << "Thursday" << '\n';
    if (t == 5) cout << "Friday" << '\n';
    if (t == 6) cout << "Saturday" << '\n';

    return 0;
}
代码2
#include <bits/stdc++.h>

using namespace std;

string ans[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

int main() {
    int a, b;
    cin >> a >> b;

    int t = 1;
    for (int i = 0; i < b; i++) {
        t *= a;
        t %= 7;
    }

    cout << ans[t] << endl;

    return 0;
}

1084:幂的末尾

 1083计算星期几 类似
提示

我们只关心末3位,即只需要 % 1000

每一次循环累乘的时候,取模

随时取模

提示2

若幂本身不足三位,在前面补零

这种情况,我们使用 if 进行判断,分情况输出

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int a, b;
    cin >> a >> b;

    int res = 1;
    for (int i = 1; i <= b; i++) {
        res *= a;
        res %= 1000;
    }

    if (res < 10) cout << "00" << res << endl;
    else if (res < 100) cout << "0" << res << endl;
    else cout << res << endl;

    return 0;
}

第二节 while语句

2020:【例4.5】第几项

提示

累加求和,当超过 m 的时候,break

使用while
while (true){
    i++;
    s += i;

    if (s > m) break;
}
使用for
for (i = 1; ; i++){
    s += i;
    if (s > m) break;
}

for (i = 1; s <= m; i++){
    s += i;
}

2021:【例4.6】最大公约数

提示

使用 for 从大到小,枚举一遍,哪个数同时是 m 和 n 的公约数

这里面要从大到小枚举

大是多大?min(m, n)

小是多小?1

代码
#include <iostream>

using namespace std;

int n, m;
int ret;

int main() {
    cin >> n >> m;
    for (int i = max(n, m); i >= 1; i--){
        if (n % i == 0 && m % i == 0){
            ret = i;
            break;
        }
    }

    cout << ret << '\n';

    return 0;
}

2022:【例4.7】最小n值

这个和 2020:【例4.5第几项是雷同的
提示

都是累加求和,满足一定条件的情况下,break

特殊一点是的,这里面是很多个分式累加

1 / i 会自动向下取整,不能得到我们想要的小数结果

这里要注意强制转换

代码
#include <bits/stdc++.h>

using namespace std;

double sum;

int main() {
    int m;
    cin >> m;

    int n = 0;
    while (sum < m) {
        n++;
        sum += 1.0 / n;
    }

    cout << n << '\n';

    return 0;
}

2023:【例4.8】数据统计

提示

没有告诉有几个数,属于不定次输入(在教程中搜索“不定次输入”复习一下)

打擂台,求最值。这是常规操作

求平均数,也需要注意强制转换

输出的时候,控制保留3位小数 printf("%.3lf", ...)

代码
#include <bits/stdc++.h>

using namespace std;

int x;
int maxn = -2e9, minn = 2e9;
int sum, n;

int main() {
    while (cin >> x){
        maxn = max(maxn, x);
        minn = min(minn, x);
        sum += x;
        n++;
    }

    printf("%d %d %.3lf\n", minn, maxn, 1.0 * sum / n);

    return 0;
}

1085:球弹跳高度的计算

这题目是有难度的
提示

难度在哪呢?在理解题面上

如何才能看得懂呢?画图,标画上10次落地的过程

在每个弹起的顶点,直接标上 几分之几 h

最后,你会发现,这直接是一个很多个分式求和

提示2

也可以写循环,模拟10次落地的过程

难点在于,总是多算一点,少算一点

试一试

代码
#include<bits/stdc++.h>
using namespace std;
int main() {
    double h, sum=0, last;
    cin >> h;

    sum = h + h + h/2 + h/4 + h/8 + h/16
        + h/32 + h/64 + h/128 + h/256;

    last = h/1024;

    cout << sum << endl << last;

    return 0;
}
代码2
#include<iostream>

using namespace std;

double ans;

int main() {
    cin>> ans;
    double sum = ans;
    for(int i = 1; i<10; i++) {
        sum += ans;
        ans /= 2;
    }
    cout<< sum <<'\n' << ans / 2 << '\n';

    return 0;
}

1086:角谷猜想

这道题目就是属于模拟题
提示

告诉我们规则,我们去执行

难点在于,怎么控制这个输出

// 使用printf, 格式化输出语句,就方便很多
printf("%d*3+1=%d\n", n, n * 3 + 1);
printf("%d/2=%d\n", n, n / 2);
代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    while (n != 1) {
        if (n % 2 == 1) {
            printf("%d*3+1=%d\n", n, n * 3 + 1);
            n = n * 3 + 1;
        } else {
            printf("%d/2=%d\n", n, n / 2);
            n = n / 2;
        }
    }
    printf("End\n");

    return 0;
}
代码2
#include<iostream>
using namespace std;
int main() {
    int n;
    cin>>n;

    while(true) {
        if(n==1) {
            cout<<"End";
            break;
        }
        if(n%2==0) {
            cout<<n<<"/2="<<n/2<<endl;
            n/=2;
        } else {
            cout<<n<<"*3+1="<<n*3+1<<endl;
            n=n*3+1;
        }
    }

    return 0;
}

1087:级数求和

这个和 2022:【例4.7最小n值 是雷同的
提示

需要注意,每一项的分式,要强制转换

1.0 / i

代码
#include<bits/stdc++.h>

using namespace std;

double s = 0;
int k;
int n = 1;

int main() {
    cin >> k;
    for(int i = 1; s <= k; i++) {
        s += 1.0 / i;
        n = i;
    }
    cout << n;

    return 0;
}

1088:分离整数的各个数

提示

这是典型的数位拆分

while (n) {
    cout << n % 10;
    n /= 10;
}

在教程上,搜索“数位拆分”,进行复习

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    while (n) {
        cout << n % 10 << ' ';
        n /= 10;
    }

    return 0;
}

1089:数字反转

这个题目也是数位拆分的应用
提示

这道题目,特殊的地方是,负数怎么处理

我们首先要回顾,整数带余除法的公式

理解一下,负数的余数问题(a = k * b + r,对于负数,也适用这个式子)

回忆结论:余数的正负号,和被除数有关

其他的,就是常规操作了

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    int t = 0;
    while (n) {
        t = t * 10 + n % 10;
        n /= 10;
    }

    cout << t;

    return 0;
}

1090:含k个3的数

提示

能够被19整除,同时恰好有k个3

这是一个逻辑与的关系

有k个3的判断,依然是数位拆分操作

代码
#include <iostream>

using namespace std;

int main() {
    int m, k;
    cin >> m >> k;

    bool flag = false;
    if (m % 19 != 0) flag = true; 

    int cnt = 0;
    while (m) {
        if (m % 10 == 3) cnt++;
        m /= 10;
    }
    if (cnt != k) flag = true;

    if (flag) cout << "NO";
    else cout << "YES";

    return 0;
}
代码2
#include <bits/stdc++.h>

using namespace std;

int m, k;

int check(int x){
    int sum = 0;
    while (x){
        if (x % 10 == 3) sum++;
        x /= 10;
    }

    return sum;
}

int main(){
    cin >> m >> k;

    if (m % 19 == 0 && check(m) == k) cout << "YES" << '\n';
    else cout << "NO" << '\n';

    return 0;
}

第三节 do-while语句

第四节 循环嵌套

2026:【例4.12】阶乘和

提示

阶乘的定义,\(i! = 1 * 2 * ... * i\)

这个问题,求 1! + 2! + 3! + ...

用两层循环控制,一层循环控制 i,一层循环求i的阶层

代码-使用两层循环
#include <bits/stdc++.h>

using namespace std;

int s, n;

int main(){
    cin >> n;

    for (int i = 1; i <= n; i++){
        int t = 1;
        for (int j = 1; j <= i; j++) t *= j;

        s += t;
    }

    cout << s << '\n';

    return 0;
}
代码2-优化到一层循环
#include <bits/stdc++.h>

using namespace std;

int s, n;

int main(){
    cin >> n;

    int t = 1;
    for (int i = 1; i <= n; i++){
        t *= i;
        s += t;
    }

    cout << s << '\n';

    return 0;
}

2027:【例4.13】三角形

提示

属于图形打印题目,首先观察规律

我们可以发现,第i行有i个'*'

两层循环,一层控制i,一层控制第i行输出几个'*'

注意,每行结束,有一个换行

代码
#include<bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= i; j++) cout << '*';
        puts("");
    }

    return 0;
}

2028:【例4.14】百钱买百鸡

提示

问题的背景,我们都很熟悉

在编程课上,我们采用枚举所有情况,判断是否符合题目中说的要求,即:

刚好100元,刚好100只鸡

用三层循环,分别枚举公鸡、母鸡、小鸡的数量

当然,我们在枚举的过程中,可以进行一些细节的完善,比如,公鸡最多只能买100/5只,母鸡最多只能买100/3只,小鸡的数量可以整除3

代码
#include <iostream>

using namespace std;

int main() {
    for (int i = 0; i <= 20; i++)  // 枚举公鸡
        for (int j = 0; j <= 33; j++) // 母鸡
            for (int k = 0; k <= 100; k += 3) // 小鸡
                if (5 * i + 3 * j + k / 3 == 100 && i + j + k == 100) 
                    cout << i << ' ' << j << ' ' << k << '\n';

    return 0;
}
代码2-优化掉一层循环
// 当我们知道公鸡、母鸡的数量,小鸡数量就是明确的
// 利用这一点,我们省掉一层循环
#include <bits/stdc++.h>

using namespace std;

int main() {
    for (int i = 0; i <= 100 / 5; i++)
        for (int j = 0; j <= 100 / 3; j++) {
            int k = 100 - i - j;
            if (i*5 + j*3 + k/3 == 100 && k % 3 == 0) printf("%d %d %d\n", i, j, k);
        }

    return 0;
}

2029:【例4.15】水仙花数

提示

这个题目,没有输入。这是没问题的

这个题目的样例,也没有给你。因为答案就是那个,给你样例,等于告诉你答案了

一层循环枚举100到999,在循环内部,对i进行拆位,个位十位百位,判断是否符合要求

满足条件的情况,计数器++

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    for (int i = 100; i <= 999; i++){
        int a = i / 100;
        int b = i / 10 % 10;
        int c = i % 10;

        if (a*a*a + b*b*b + c*c*c == i) cout << i << '\n';
    }

    return 0;
}

2030:【例4.16】找素数

提示

素数,就是质数

我们利用质数的定义,解决问题。

质数的定义是,除了1和它本身之外,没有其他约数

一层循环枚举a到b的数,在循环里,再用一层循环判断i是不是质数(就是for一遍,从2到i-1,能不能找到i的约数)

代码
#include <bits/stdc++.h>

using namespace std;

int a, b;

int main(){
    cin >> a >> b;
    for (int i = max(a, 2); i <= b; i++){
        bool flag = false;
        for (int j = 2; j < i; j++) if (i % j == 0){
            flag = true;
            break;
        }

        if (!flag) cout << i << '\n';
    }

    return 0;
}

2031:【例4.17】四位完全平方数

提示

aabb,就是千位和百位相同,十位和个位相同

for循环,从1000枚举到9999,枚举所有的四位数

在循环里,判断是否满足aabb的形状,同时,也是完全平方数

完全平方数的判断是这样的

int x = sqrt(i);
if (x * x == i) cout << i << '\n';

以后,就这样写就可以了

代码
#include<bits/stdc++.h>

using namespace std;

int main() {
    for(int i=1000;i<=9999;i++)
        if(i%10==i/10%10 && i/100%10==i/1000) {
            int x = sqrt(i);
            if (x * x == i) cout << i << '\n';
        }

    return 0;
}

2032:【例4.18】分解质因数

提示

分解质因数,也叫分解质因子,我更喜欢后者的叫法

这道题目,涉及两个问题,

1、如何分解

2、如何控制'*'的输出

第一次写这种问题的同学,直接把示范代码学习会,然后自己写,就可以了。

写一次,以后就会了

代码
#include <iostream>

using namespace std;

int main() {
    int n;
    cin >> n;
    bool flag = false;
    cout << n << "=";
    for(int i = 2; i <= n; i++) {
        while(n % i == 0) {
            if(flag) cout << "*";
            flag = true;

            cout << i;
            n /= i;
        }
    }
    return 0;
}
代码2-从2枚举到根号n

这个方法,也要学习掌握,并且,要去理解,为什么在最后要判断n>1

此时n>1,代表了什么

#include <bits/stdc++.h>

using namespace std;

int main(){
    int n;
    cin >> n;

    bool flag = false;
    printf("%d=", n);
    for (int i = 2; i <= n / i; i++){
        while (n % i == 0){
            if (flag) printf("*");
            printf("%d", i);
            n /= i;
            flag = true;
        }
    }

    if (n > 1){
        if (flag) printf("*");
        printf("%d", n);
    }

    return 0;
}

2033:【例4.19】阶乘之和

和 2026:【例4.12】阶乘和,一样
提示

不同的地方,就是要求末6位,即随时取模

代码
#include <bits/stdc++.h>

using namespace std;

const int MOD = 1e6;

int n, ret;
int t = 1;

int main(){
    cin >> n;
    for (int i = 1; i <= n; i++){
        t *= i;
        t %= MOD;

        ret += t;
        ret %= MOD;
    }

    cout << ret << '\n';

    return 0;
}

1091:求阶乘的和

和 2026:【例4.12】阶乘和,一样

1092:求出e的值

和 2026:【例4.12】阶乘和,类似
提示

这里求 \(i!\),作为分母使用,累加 \(\frac{1}{i!}\)

注意,整数除以整数,会自动向下取整。

代码
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n;
double ret = 1;

int main(){
    cin >> n;

    ll t = 1ll;
    for (int i = 1; i <= n; i++){
        t *= i;
        ret += 1.0 / t;
    }

    printf("%.10lf\n", ret);

    return 0;
}

1093:计算多项式的值

多项式(英语:Polynomial)是代数学中的基础概念,

是由称为未知数的变量和称为系数的常数通过有限次

加减法、乘法以及自然数幂次的乘方运算得到的代数表达式。
提示

给了x的值,给了最高次幂数n,求多项式的值

我们从后向前看这个式子,就好看了

从0次幂开始,1次幂,2次幂,3次幂,...

我们就写两层循环,一层循环控制i,维护几次幂的问题,在循环里,再去计算x的i次幂

这里x的i次幂,并不需要从新求,类似求阶乘和的问题,可以在外面整体维护,一边for一边维护

\(x^n\),是指n个x相乘

\(x^0\),是1。任何正整数的0次幂,是1

代码
#include <bits/stdc++.h>

using namespace std;

double sum = 1.0;

int main(){
    int n;
    double x;
    cin >> x >> n;

    double t = 1.0;
    for (int i = 1; i <= n; i++){
        t *= x;
        sum += t;
    }

    printf("%.2lf\n", sum);

    return 0;
}

1094:与7无关的数

提示

判断和7是否有关,能被7整除,数位当中有7这个数字

采用while循环,进行数位拆分。也因为n<100,可以直接判断个位十位上的数字。

整体上,for一遍,从1-n,判断i是否和7有关

代码
#include<iostream>
using namespace std;
int main() {
    int n, sum = 0;
    cin >> n;

    for(int i = 1; i <= n; i++) 
        if(i%7!=0 && i/10 !=7 && i%10!=7 ) sum += i * i;

    cout << sum;

    return 0;
}
代码2
#include <iostream>

using namespace std;

int sum;

// 模块化编程
// 程序设计
bool check(int x){
    while (x){
        if (x % 10 == 7) return false;
        x /= 10;
    }

    return true;
}

int main(){   //主函数
    int n;
    cin >> n;

    for (int i = 1; i <= n; i++)
        if (i % 7 != 0 && check(i))
            sum += i * i;

    cout << sum << '\n';

    return 0;
}

1095:数1的个数

提示

for一遍,从1-n,判断i有几个1

n没有给具体多少位,用数位拆分

代码
#include <bits/stdc++.h>

using namespace std;

int check(int x)
{
    int sum = 0;
    while (x)
    {
        if (x % 10 == 1) sum++;
        x /= 10;
    }

    return sum;
}

int main()
{
    int n;
    cin >> n;

    int cnt = 0;
    for (int i = 1; i <= n; i++)
    {
        cnt += check(i);
    }

    cout << cnt << endl;

    return 0;
}

1096:数字统计

提示

for循环,从L到R,判断i当中有几个2,用cnt维护

代码
#include <bits/stdc++.h>

using namespace std;

int check(int x) {
    int s = 0;
    while (x) {
        if (x % 10 == 2) s++;
        x /= 10;
    }

    return s;
}

int main() {
    int L, R;
    cin >> L >> R;

    int sum = 0;
    for (int i = L; i <= R; i++) {
        sum += check(i);
    }

    cout << sum << "\n";

    return 0;
}

1097:画矩形

提示

首先要认真阅读输入描述,分清楚输入的4个数,代表的是什么。

分别代表高、宽、符号、空心还是实心

用if判断,实心图案,一种写法;空心图案,一种写法

实心图案,只需要两层for循环,搞定

空心图案,观察什么情况输出符号,当第一行第一列最后一行最后一列的情况

怎么判断第一行第一列最后一行最后一列?

提示2
if (i == 1 || i == n || j == 1 || j == m)
代码
#include <iostream>

using namespace std;

int main() {
    int n, m, flag;
    char c;
    cin >> n >> m >> c >> flag;

    if (flag == 1) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) cout << c;
            cout << endl;
        }
    }
    else {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) 
                if (i == 1 || i == n || j == 1 || j == m) cout << c;
                else cout << ' ';

            cout << endl;
        }
    }


    return 0;
}

1098:质因数分解

提示

题目中,已经明确指出,n是两个不同质数的乘积。这两个质数,就是n的质因子。

我们可以从n-1往小进行枚举,当枚举到一个可以乘除n的数时,就是我们要的较大的质因子。

也可以从2开始往大进行枚举,当枚举到一个可以乘除n的数时,n / i 就是我们要的较大质因子。

代码
#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin >> n;

    for (int i = 2; i <= n / i; i++) {
        if (n % i == 0) {
            cout << n / i << endl;
            break;
        }
    }

    return 0;
}

1099:第n小的质数

提示

从2开始枚举,判断i是不是质数。如果是,计数器++。

当计数器等于n时,就找到了我们要找的数。

这里在代码实现上,我们判断i是不是质数的环节,采用自定义函数进行处理。

这个自定义函数,判断质数的代码,属于代码模板,要严格模仿,闭眼睛可以操练。

代码
#include <iostream>

using namespace std;

bool is_prime(int x) {
    for (int i = 2; i <= x / i; i++)
        if (x % i == 0) return false;

    return true;
}

int main() {
    int n;
    cin >> n;

    int x = 2, cnt = 0;
    while (true) {
        if (is_prime(x)) {
            cnt++;
            if (cnt == n) break;
        }
        x++;
    }
    cout << x << '\n';

    return 0;
}

1100:金币

先复述题意,用自己话表达一遍,并写出来。再往下进行
提示

1枚金币拿1天,2枚金币拿2天,..., n枚金币拿n天

这道题目,很多同学觉得复杂,第一个问题,就是你没有读懂题目。

第二个困难才是,如何表达拿k天的问题

拿k天,就是整体有一个计数器,维护次数,就可以了。

代码
#include<iostream>

using namespace std;

int sum;

int main(){
    int n;
    cin >> n;

    for (int i = 1; n; i++) 
        for (int j = 1; j <= i && n; j++) 
            sum += i, n--;

    cout << sum;

    return 0;
}
代码2
#include <bits/stdc++.h>

using namespace std;

int k;
int sum;

int main() {
    cin >> k;

    int n = 1;
    while (n <= k) {
        sum += n * n;
        k -= n;
        n++;
    } 

    sum += n * k;
    cout << sum << '\n';

    return 0;
}

1101:不定方程求解

提示

在这个不定方程中,换句话说,在这个式子中,

x的取值范围是,[0, c/a]

y的取值范围是,[0, c/b]

我们可以两层循环,分别枚举x和y,判断等于是否成立。如果成立,计数器++

代码
#include <iostream>

using namespace std;

int cnt;
int a, b, c;

int main(){
    cin >> a >> b >> c;

    for (int x = 0; x <= c / a; x++)
        for (int y = 0; y <= c / b; y++)
            if (a * x + b * y == c)
                cnt++;

    cout << cnt;

    return 0;
}
代码2-减少一层循环
#include <iostream>

using namespace std;

//ax+by=c
int a, b, c;
int cnt;

int main(){
    cin >> a >> b >> c;
    for (int x = 0; x <= c / a; x++)
        if ((c - a * x) % b == 0) cnt++;

    cout << cnt << '\n';

    return 0;
}