第一章 模拟

1 什么是模拟

首先,我们来深入理解“模拟”这一词汇在广义上的含义。在百度等搜索引擎中,“模拟”常被解释为:

通过构建或复现某种情境、过程或系统,以预测或展示其行为的方法。

那么,当我们将这一概念应用于算法领域时,模拟算法便应运而生:

简而言之,模拟算法即是遵循题目所描述的具体步骤,通过编程手段一一执行这些步骤,从而忠实地模拟出题目要求的过程,并最终得到相应的结果。

2 模拟的优缺点

2.1 模拟算法的魅力

模拟算法的魅力在于它直接反映了人类面对问题时的最原始、最直观的思维方式

比如,当题目要求我们给每个数加上一个特定的值A时,我们不会立即去寻找复杂的数学公式或算法优化,而是直接遍历每个数,逐一加上A。同样,如果题目要求我们从一组数中删除最小的数,我们也会自然而然地想到先找到这个最小的数,然后再将其从集合中移除。

2.2 优点

直观性:模拟算法直接反映了问题的实际操作流程,使得理解和实现都变得相对简单。

灵活性:对于不同的问题,可以通过调整模拟的步骤来适应,具有很好的通用性和灵活性。

2.3 缺点

效率可能不高:对于一些复杂的问题,如果直接模拟,可能会涉及大量的计算步骤,导致算法效率较低。(时空复杂度过高)

2.4 总结:

 这种直接、朴素的方法虽然可能在某些情况下不是最高效的,但它却因其简单易懂、易于实现而备受青睐。在解决复杂问题或进行算法设计时,模拟算法往往是一个很好的起点,它能帮助我们更好地理解问题,并为后续的优化提供基础。

3 问题实例

3.1 成绩统计

[蓝桥杯] 省赛真题 成绩统计

题目描述

小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。

如果得分至少是 60 分,则称为及格。如果得分至少为 85 分,则称为优秀。

请计算及格率和优秀率,用百分数表示,百分号前的部分四舍五入保留整 数。

输入描述

输入的第一行包含一个整数 𝑛 (1≤𝑛≤10^{4})n (1≤n≤10^{4}),表示考试人数。

接下来 𝑛n 行,每行包含一个 0 至 100 的整数,表示一个学生的得分。

输出描述

输出两行,每行一个百分数,分别表示及格率和优秀率。百分号前的部分 四舍五入保留整数。

示例:

输入

7
80
92
56
74
88
100
0

输出

71%
43%

 

思路:

直接遍历所有成绩数据,分别统计及格和优秀的同学数量,然后计算百分比。注意输出时要四舍五入保留整数。

代码: 

#include <bits/stdc++.h>  
using namespace std;  
  
int main()  
{  
    int n;  
    cin >> n; // 读取学生数量  
    int pass = 0, excellent = 0;  
    for (int i = 0; i < n; i++)  
    {  
        int score;  
        cin >> score; // 读取每个学生的成绩  
        if (score >= 60)  
            pass++;  
        if (score >= 85)  
            excellent++;  
    }  
    int passRate = (pass * 100 + n / 2) / n; // 四舍五入  
    int excellentRate = (excellent * 100 + n / 2) / n; // 四舍五入  
    cout << passRate << '%' << endl;  
    cout << excellentRate << '%';  
    return 0;  
}

3.2 门牌制作 

[蓝桥杯] 省赛真题 门牌制作

题目描述

小蓝要为一条街的住户制作门牌号。

这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。

小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个字符 0,2 个字符 1,1 个字符 7。

请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?

 思路:

遍历1到2020的每个数字,对每个数字使用取模和整除操作来分解其每一位,并判断该位是否为'2'。如果是,则计数器加1。最后输出总和。

代码:

#include <bits/stdc++.h>  
using namespace std;  
  
int countTwos(int a) // 判断一个数字中有多少个'2'  
{  
    int num = 0;  
    while (a > 0)  
    {  
        int x = a % 10;  
        if (x == 2)  
            num++;  
        a = a / 10;  
    }  
    return num;  
}  
  
int main()  
{  
    int sum = 0;  
    for (int i = 1; i <= 2020; i++)  
    {  
        sum += countTwos(i); // 依次求和  
    }  
    cout << sum;  
    return 0;  
}

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值