问题描述:
试题编号: | 201612-2 |
试题名称: | 工资计算 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 小明的公司每个月给小明发工资,而小明拿到的工资为交完个人所得税之后的工资。假设他一个月的税前工资(扣除五险一金后、未扣税前的工资)为S元,则他应交的个人所得税按如下公式计算: 输入格式 输入的第一行包含一个整数T,表示小明的税后所得。所有评测数据保证小明的税前工资为一个整百的数。 输出格式 输出一个整数S,表示小明的税前工资。 样例输入 9255 样例输出 10000 评测用例规模与约定 对于所有评测用例,1 ≤ T ≤ 100000。 |
一道数学气息浓厚的题(`・ω・´)
正常做法是逆运算,但我感觉挺麻烦,一开始想暴力枚举,没想到超时了!!偏不信这个邪,而后灵光一闪,二分呀!!
遂有以下AC代码:
#include<iostream>
#include<algorithm>
#include<string>
#include<iomanip>
#include<vector>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
int fun(int x)//税前x元,税后fun(x)元
{
int ans=0,A=x-3500;
if(A<=0) return x;
if(A<=1500) ans=A*0.03;
else if(A<=4500) ans=45+(A-1500)*0.1;
else if(A<=9000) ans=345+(A-4500)*0.2;
else if(A<=35000) ans=1245+(A-9000)*0.25;
else if(A<=55000) ans=7745+(A-35000)*0.3;
else if(A<=80000) ans=13745+(A-55000)*0.35;
else ans=22495+(A-80000)*0.45;
return x-ans;
}
int main()
{
int T;cin>>T;
if(T<=3500)
{cout<<T;return 0;}
int lb=0,ub=1<<30;//初始化左边界和右边界
while(lb+1<ub)
{
int mid=(lb+ub)/2;
int money=fun(mid);
if(money<T) lb=mid;
else if(money>T) ub=mid;
else if(money==T) //满足条件,可结束循环
{
cout<<mid;break;
}
}
}
附上正常做法AC代码,来自https://blog.csdn.net/papaweilun/article/details/77987423
#include<iostream>
using namespace std;
int main()
{
int n=0;
while(cin>>n)
{
if(1<=n&&n<3500)
cout<<n<<endl;
if(3500<=n&&n<4955)
cout<<(n-105)*100/97<<endl;
if(4955<=n&&n<7655)
cout<<(n-455)*10/9<<endl;
if(7655<=n&&n<11255)
cout<<(n-1255)*10/8<<endl;
if(11255<=n&&n<30755)
cout<<(n-1880)*100/75<<endl;
if(30755<=n&&n<44755)
cout<<(n-3805)*10/7<<endl;
if(44755<=n&&n<61005)
cout<<(n-6730)*100/65<<endl;
if(61005<=n)
cout<<(n-15080)*100/55<<endl;
}
}