
第二章 2.1 简单模拟
✏️ 关于专栏:专栏用于记录
prepare for the coding test。
1. 简单模拟
简单模拟题目不需要复杂算法,直接按照题意一步步模拟即可。
1.1 促销计算
题目描述
某百货公司为了促销,采用购物打折的优惠方法:
- 购物金额 > 5000 元,按 8 折优惠;
- 3000 < 金额 ≤ 5000 元,按 8.5 折优惠;
- 2000 < 金额 ≤ 3000 元,按 9 折优惠;
- 1000 < 金额 ≤ 2000 元,按 9.5 折优惠;
- 金额 ≤ 1000 元,不打折。
编写程序,输入多组购物金额,计算并输出对应的折扣和支付金额。
输入输出格式
- 输入:多行,每行一个整数,表示某次购物的金额。
- 输出 :对应各行,格式为 discount=折扣,pay=支付金额。
样例
            
            
              text
              
              
            
          
          输入:            
850               
1230              
5000              
3560              
输出:
discount=1,pay=850
discount=0.95,pay=1168.5
discount=0.8,pay=4000
discount=0.85,pay=3026C++ AC 代码
            
            
              cpp
              
              
            
          
          #include <bits/stdc++.h>
using namespace std;
int main() {
    int pay;
    while (cin >> pay) {
        if (pay <= 1000)
            cout << "discount=1,pay="  << pay       << endl;
        else if (pay <= 2000)
            cout << "discount=0.95,pay=" << pay * 0.95 << endl;
        else if (pay <= 3000)
            cout << "discount=0.9,pay="  << pay * 0.9  << endl;
        else if (pay <= 5000)
            cout << "discount=0.85,pay=" << pay * 0.85 << endl;
        else
            cout << "discount=0.8,pay="  << pay * 0.8  << endl;
    }
    return 0;
}小结:本题关键在于分段判断并计算折扣,属于典型的区间模拟题。
1.2 求 1 到 n 的和
题目描述
输入一个整数 n,输出 1 + 2 + ... + n 的和。
输入输出格式
- 输入 :一个整数 n(n ≤ 100)。
- 输出 :从 1 累加到 n的结果。
样例
            
            
              text
              
              
            
          
          输入:5
输出:15C++ AC 代码
            
            
              cpp
              
              
            
          
          #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 << endl;
    return 0;
}小结:简单累加循环,时间复杂度 O(n)。
1.3 计算 Sn
题目描述
计算数列 Sn=a+aa+aaa+⋯+aaa...a⏟n 个 aS_n = a + aa + aaa + \dots + \underbrace{aaa\dots a}_{n\text{ 个 }a} 的和,其中 a 为 1 位数。
例如:当 a=2, n=5 时,需计算 2 + 22 + 222 + 2222 + 22222。
输入输出格式
- 输入 :两个整数 a, n(1 < a, n < 10)。
- 输出:上述数列的总和。
样例
            
            
              text
              
              
            
          
          输入:2 5
输出:24690C++ AC 代码
            
            
              cpp
              
              
            
          
          #include <bits/stdc++.h>
using namespace std;
int main() {
    int a, n;
    cin >> a >> n;
    int sum = 0;
    int term = a;
    for (int i = 1; i <= n; i++) {
        sum += term;
        term = term * 10 + a;  // 在末尾添加一位 'a'
    }
    cout << sum << endl;
    return 0;
}小结 :利用
term = term * 10 + a迭代生成每一项,避免字符串操作。
1.4 利润提成计算
题目描述
根据企业利润分段计算奖金:
| 利润区间 (元) | 提成比例 | 
|---|---|
| ≤ 100 000 | 10% | 
| 100 000 < I ≤ 200 000 | 7.5% | 
| 200 000 < I ≤ 400 000 | 5% | 
| 400 000 < I ≤ 600 000 | 3% | 
| 600 000 < I ≤ 1 000 000 | 1.5% | 
| > 1 000 000 | 1% | 
编写程序,输入当月利润 I,输出应发奖金总额。
输入输出格式
- 输入 :一个整数 I。
- 输出:对应的奖金金额(浮点数)。
样例
            
            
              text
              
              
            
          
          输入:900
输出:90C++ AC 代码
            
            
              cpp
              
              
            
          
          #include <bits/stdc++.h>
using namespace std;
double calcBonus(int profit) {
    static const vector<pair<int,double>> tiers = {
        {100000, 0.10}, {200000, 0.075}, {400000, 0.05},
        {600000, 0.03},  {1000000, 0.015}, {INT_MAX, 0.01}
    };
    double bonus = 0;
    int prev = 0;
    for (auto &[limit, rate] : tiers) {
        if (profit > prev) {
            int diff = min(profit, limit) - prev;
            bonus += diff * rate;
            prev = limit;
        } else break;
    }
    return bonus;
}
int main() {
    int I;
    cin >> I;
    cout << fixed << setprecision(2) << calcBonus(I) << endl;
    return 0;
}小结:采用分段累加方法,代码更易扩展和维护。
1.5 身份证校验
题目描述
校验中国二代身份证号:共 18 位,最后一位为校验位。校验方法:
- 
前 17 位各数字分别乘以相应权值: w = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]。
- 
将所得乘积求和 S,取S % 11 = x。
- 
将 x与校验字符映射:x 0 1 2 3 4 5 6 7 8 9 10 校验位 1 0 X 9 8 7 6 5 4 3 2 
若第 18 位字符与映射结果一致,则身份证合法。
输入输出格式
- 输入 :多行,每行一个 18 位身份证号(末位可能为大写 X)。
- 输出 :对应每行,合法输出 ID Corrent,否则输出ID Wrong。
样例
            
            
              text
              
              
            
          
          输入:
1222222222
111111111111111111
341181198809150011
11010119900307387X
150102199003075131
150102200003075131
输出:
ID Wrong
ID Wrong
ID Corrent
ID Corrent
ID Corrent
ID WrongC++ AC 代码(优化版)
            
            
              cpp
              
              
            
          
          #include <bits/stdc++.h>
using namespace std;
int main() {
    static const int weights[17] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    static const char mapping[11] = {'1','0','X','9','8','7','6','5','4','3','2'};
    string id;
    while (cin >> id) {
        if (id.size() != 18) {
            cout << "ID Wrong" << endl;
            continue;
        }
        int sum = 0;
        for (int i = 0; i < 17; ++i)
            sum += (id[i] - '0') * weights[i];
        int mod = sum % 11;
        cout << (mapping[mod] == id[17] ? "ID Corrent" : "ID Wrong") << endl;
    }
    return 0;
}小结:使用数组与常量映射,代码简洁易读。
