CCF-CSP 2016-2 工资计算 暴力求解+二分法两种方法 满分题解

CCF-CSP 2016-2 工资计算 暴力求解+二分法两种方法 满分题解

题目链接:CCF-CSP 2016-2 工资计算
在这里插入图片描述

暴力求解思路:

  • 首先计算出在各个工资范围内的税费,设置一个int数组存储,即int v[7]={45,300,900,6500,6000,8750,9000};例如:45=1500*0.03
  • 然后根据税后所得判断实际工资的具体范围,列出具体方程,求解出实际工资
  • 在计算时需要注意,求解实际工资时需要加上之前范围内的税费
  • 同时,需要注意工资范围的边界,例如:实际工资为8100到手只要7735,但是7735却在5000~8000的范围内,不在8000~12500的范围内,所以我们在5000~8000的范围内需要特判,如果大于等于7735,就需要按照8000~12500的范围方程进行求解
  • 一个小提示:这里的s设置为double类型,否则在70080即实际工资为100000时,最后只能得到99999的结果
  • 在选择数据范围时,主要到税前工资为一个整百的数
  • 该方法只是纯粹的数学方法,实现过程十分繁琐,但是思路简单易懂;

具体代码如下:

#include <iostream>
#include <algorithm>
using namespace std;
int t;
double s;//double转int时的精度有问题
int v[7]={45,300,900,6500,6000,8750,9000};//税费
int main()
{
    cin>>t;
    if(t<=3500)
    {
        s = t;
    }
    else if(t>3500&&t<=5000)//5045是5100的实发工资
    {
        int temp = t - 3500;
        s = (temp+3395)/0.97;//temp+(s-3500)*0.03=s-3500
    }
    else if(t>5000&&t<=8000)
    {
        int temp =t+v[0];
        if(temp>=7735)//7735是8100的实发工资
        {
            s = (temp-1600)*0.8;
        }
        else s = (temp-500)/0.9;//temp+(s-5000)*0.1=s
    }
    else if(t>8000&&t<=12500)
    {
        int n = 1;
        int temp = t;
        for(int i=0;i<=n;i++)
        {
            temp+=v[i];
        }
        if(temp>=11330)//11330是12600的实发工资
        {
            temp+=v[n+1];
            s = (temp-3125)/0.75;
        }
        else s = (temp-1600)/0.8;//temp+(s-8000)*0.2=s
    }
    else if(t>12500&&t<=38500)
    {
        int n = 2;
        int temp = t;
        for(int i=0;i<=n;i++)
        {
            temp+=v[i];
        }
        if(temp>=30825)//30825是38600的实发工资
        {
            temp += v[n+1];
            s = (temp-11550)/0.7;
        }
        else s = (temp-3125)/0.75;//temp+(s-12500)*0.25=s
    }
    else if(t>38500&&t<=58500)
    {
        int n = 3;
        int temp = t;
        for(int i=0;i<=n;i++)
        {
            temp+=v[i];
        }
        if(temp>=44820)//44820是58600的实发工资
        {
            temp +=v[n+1];
            s = (temp-20475)/0.65;
        }
        else s = (temp-11550)/0.7;//temp+(s-38500)*0.3=s
    }
    else if(t>58500&&t<=83500)
    {
        int n = 4;
        int temp = t;
        for(int i=0;i<=n;i++)
        {
            temp+=v[i];
        }
        if(temp>=61060)//61060是83600的实发工资
        {
            temp +=v[n+1];
            cout<<temp<<endl;
            s =(temp-37575)/0.55;
        }
        else s = (temp-20475)/0.65;//temp+(s-58500)*0.35=s
    }
    else if(t>83500&&t<=100000)
    {
        int n = 5;
        int temp = t;
        for(int i=0;i<=n;i++)
        {
            temp+=v[i];
        }
        s = (temp-37575)/0.55;//temp+(s-83500)*0.45=s
    }
    cout<<s<<endl;
    return 0;
}

注意:此方法在其他测试网站上可以AC,但是在CCF-CSP官网上却只有50分,欢迎大佬讨论!!!


二分法求解思路:

  • 该方法在方法一的基础上进行了优化,不需要计算出各个工资范围之间的税费
  • 直接利用二分查找,找到符合条件的实际工资
  • get函数是计算税后工资

具体代码如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int t;
//计算税前工资
int get(int k){
    int a[] = {0, 1500, 4500, 9000, 35000, 55000, 80000, 1000000};//工资范围
    double r[] = {0, 0.03, 0.1, 0.2, 0.25, 0.3, 0.35, 0.45};//税率

    if(k <= 3500) return k;
    int tax = k - 3500;
    double sum = 0;//记录减去的税费
    for(int i = 1; i <= 7; i ++)
    {
        if(tax >= a[i])
        {
            sum += (a[i] - a[i - 1]) * r[i];//加上减去的税
        }
        else
        {
            sum += (tax - a[i - 1]) * r[i];
            break;
        }
    }
    return k - sum;
}

int main()
{
    cin >> t;
    int l = t, r = t * 2;//设置二分范围
    while (l < r)
    {
        int mid = (l + r) >> 1;
        if(get(mid) >= t) r = mid;
        else l = mid + 1;
    }
    cout <<l<<endl;
    return 0;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值