codevs 2988 保留小数 2
2988 保留小数 2
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 白银 Silver
题目描述 Description
这个难度是吸引你点进来的。(其实难度挺大)
保留小数 的加强版。加强了数据和描述。
有一个实数,要求保留k位小数。请输出结果。
输入描述 Input Description
两行。
第一行,要保留的数;
第二行,k
输出描述 Output Description
输出保留小数的结果。(四舍五入)
样例输入 Sample Input
(样例1)
8
2
(样例2)
7.03
1
(样例3)
7.0003
0
(样例4)
9.9
-1
(样例5)
0.99
3
(样例6)
-9999.2
0
样例输出 Sample Output
(样例1)8.00
(样例2)7.0
(样例3)7
(样例4)10
(样例5)0.990
(样例6)-9999
数据范围及提示 Data Size & Hint
k在longlong范围内;
要保留的小数在10000位以内。
如果k为负数,则向前保留。
要保留的小数可以为负数。
/* 这个题竟然是白银题! 可怜的我连怎么保留负数位都不知道! ╮(╯▽╰)╭ 无良的我只能粘题解了 */ #include<iostream> #include<string> using namespace std; string process(string s,long long k) { bool negative=s.at(0)=='-'; if(negative) s=s.substr(1,s.size()-1); unsigned point=s.find('.'); if(point == string::npos) { s.append("."); point=s.size()-1; } if(k>0) { if(point+(unsigned)k>=s.size()) { int length=point+k-s.size()+1; int i; for(i=0;i<length;i++)s.append("0"); if(negative)s='-'+s; return s; } else { string result=s.substr(0,point+k+1); if(point+(unsigned)k+1<s.size()&&s.at(point+k+1)>'4') { int i=point+k; while(i>=0&&(result.at(i)=='.'||result.at(i)=='9')) { if(result.at(i)=='9')result.at(i)='0'; --i; } if(i>=0)++result.at(i); else result='1'+result; } if(negative)result = '-' + result; return result; } } else if(k==0) { string result=s.substr(0,point); if(point+1<s.size()&&s.at(point+1)>'4') { int i=point-1; while(i>=0&&result.at(i)=='9')result.at(i--)='0'; if(i>=0)++result.at(i); else result='1'+result; } if(negative)result='-'+result; return result; } else { string result=s.substr(0,point); long long i=1; while(k--<-1) { result.at(result.size()-i)='0'; ++i; } bool up=result.at(result.size()-i)>'4'; result.at(result.size()-i)='0'; if(up) { i=result.size()-i-1; while(i>=0&&result.at(i)=='9')result.at(i--) = '0'; if(i>=0)++result.at(i); else result = '1' + result; } if(negative)result='-'+result; return result; } } int main() { string s; long long k; cin>>s>>k; cout<<process(s, k)<<endl; return 0; }
年年岁岁花相似,岁岁年年人不同。