【工资计算 / 2】

15 篇文章 0 订阅

题目

a3be384e5a5c4cc5b6359f8c52c2e5a7.png

枚举

#include <bits/stdc++.h>
using namespace std;
int T;
int a[] = {0,1500,4500,9000,35000,55000,80000,1000000};
int b[] = {0,3,10,20,25,30,35,45};
int check(int x)
{
    if(x <= 3500) return x;

    x -= 3500;
    int tax = 0;
    for(int i = 1; i < 8; i++)
    {
        if(x >= a[i-1])
        {
            tax += (min(x, a[i]) - a[i-1]) / 100 * b[i];
        }
    }

    return x + 3500 - tax;
}
int main()
{
    cin >> T;

    for(int x = 0; ; x += 100)
    {
        if(check(x) == T)
        {
            cout << x;
            break;
        }
    }
    return 0;
}

右区间二分

#include <bits/stdc++.h>
using namespace std;
int T;
int a[] = {0, 1500, 4500, 9000, 35000, 55000, 80000, 1000000};
int b[] = {0, 3, 10, 20, 25, 30, 35, 45};
int check(int x)
{
    if(x <= 3500) return x;
 
    x -= 3500;
    double tax = 0;
    for(int i = 1; i < 8; i++)
    {
        if(x >= a[i-1])
        {
            tax += (double)(min(x, a[i]) - a[i-1]) / 100 * b[i];
        }
    }
 
    return x + 3500 - tax;
}
int main()
{
    cin >> T;
 
    int l = T, r = T * 2;
 
    while (l < r){
        int mid = (l + r) >> 1;
        if(check(mid) >= T) r = mid;
        else l = mid + 1;
    }
 
    cout << l;
    return 0;
}

左区间二分(错,注意答案必须是100的倍数,结合精度丢失,可以判断必须采用右区间二分)

比如check(10000) (右区间边界)= check(10001)(左区间边界) = 9255

check(9999) < 9255

如果右区间二分,会得到10000,左区间二分会得到 >= 10001的值

#include <bits/stdc++.h>
using namespace std;
int T;
int a[] = {0, 1500, 4500, 9000, 35000, 55000, 80000, 1000000};
int b[] = {0, 3, 10, 20, 25, 30, 35, 45};
int check(int x)
{
    if(x <= 3500) return x;
 
    x -= 3500;
    double tax = 0;
    for(int i = 1; i < 8; i++)
    {
        if(x >= a[i-1])
        {
            tax += (double)(min(x, a[i]) - a[i-1]) / 100 * b[i];
        }
    }
 
    return x + 3500 - tax;
}
int main()
{
    cin >> T;
 
    int l = T, r = T * 2;
 
    while (l < r){
        int mid = (l + r + 1) >> 1;
        if(check(mid) <= T) l = mid;
        else r = mid-1;
    }
 
    cout << l;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值