蓝桥杯试题 算法训练 猴子吃包子
题目
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
从前,有一只吃包子很厉害的猴子,它可以吃无数个包子,但是,它吃不同的包子速度也不同;肉包每秒钟吃x个;韭菜包每秒钟吃y个;没有馅的包子每秒钟吃z个;现在有x1个肉包,y1个韭菜包,z1个没有馅的包子;问:猴子吃完这些包子要多久?结果保留p位小数。
输入格式
输入1行,包含7个整数,分别表示吃不同包子的速度和不同包子的个数和保留的位数。
输出格式
输出一行,包含1个实数,表示吃完所有包子的时间。
样例输入
4 3 2 20 30 15 2
样例输出
22.50
数据规模和约定
0<x<100;0<y<100;0<z<100;0<x1<=1000000;0<y1<=10000000;0<z1<=10000000;0<p<=1000
解题思路
本题咋一看十分简单,ans=x1/x+y1/y+z1/z (1),最后设置一个小数点后保留的长度即可。但题中的坑就在这个长度p,p最大可取到1000,这是基本数据类型达不到的精度,所以需要手动编写小数部分计算过程。初始思想是分别计算x1/x, y1/y, z1/z的整数部分和小数部分,后来发现可以优化,即将(1)式同分,ans=(x1yz+y1xz+z1xy)/(xyz),这样整数部分和小数部分便可以一次计算完毕。
代码
这是第一种分开算的思想,通过了所有测试用例。
#include <iostream>
#define N 1002
using namespace std;
char xn[N];
char yn[N];
char zn[N];
char ans[N];
int main(){
int x,y,z,x1,y1,z1,p;
cin>>x>>y>>z>>x1>>y1>>z1>>p;
for(int j=0;j<=p;j++){//初始化
xn[j]='0';
yn[j]='0';
zn[j]='0';
}
int ansx,ansy,ansz;
ansx=x1/x;
ansy=y1/y;
ansz=z1/z;//分别计算整输部分
char ch;
int temp1,temp2;
int i=0;
//分别计算小数部分
temp1=x1%x;
do{
temp2=temp1*10/x;
ch=temp2+'0';
xn[i++]=ch;
temp1=temp1*10%x;
}while(ch!='0'&&i<p+1);
i=0;
temp1=y1%y;
do{
temp2=temp1*10/y;
ch=temp2+'0';
yn[i++]=ch;
temp1=temp1*10%y;
}while(ch!='0'&&i<p+1);
i=0;
temp1=z1%z;
do{
temp2=temp1*10/z;
ch=temp2+'0';
zn[i++]=ch;
temp1=temp1*10%z;
}while(ch!='0'&&i<p+1);
//大整数加
int fa=0;
int temp;
for(i=p;i>=0;i--){
x=xn[i]-'0';
y=yn[i]-'0';
z=zn[i]-'0';
temp=x+y+z+fa;
fa=temp/10;
if(i==p&&temp%10>=5){//四舍五入
fa+=1;
}
ans[i]=(temp%10)+'0';
}
ans[p]='\0';
int intpart=ansx+ansy+ansz+fa;
cout<<intpart<<"."<<ans<<endl;
}
整合到一起计算的方法,蓝桥的第四个测试用例错了,哪位朋友如果看出来原因了请告诉我了!
#include <iostream>
#define N 1002
using namespace std;
char ans[N];
int main(){
int x,y,z,x1,y1,z1,p,den,num;
cin>>x>>y>>z>>x1>>y1>>z1>>p;
for(int j=0;j<=p;j++){
ans[j]='0';
}
num=x1*y*z+y1*x*z+z1*x*y;//分子
den=x*y*z;//分母
int intpart= num/den;
char ch;
int temp1,temp2,i=0;
temp1=num%den;
do{
temp2=temp1*10/den;
ch=temp2+'0';
ans[i++]=ch;
temp1=temp1*10%den;
}while(ch!='0'&&i<p+1);//多算一位,为了最后的四舍五入
if(ans[p]-'0'<5){//不需要进位
ans[p]='\0';
cout<<intpart<<"."<<ans<<endl;
return 0;
}
int fa=1;//舍去p+1位时需要进位
i=p-1;
while((fa==1)&&(i>=0)){
temp1=ans[i]-'0'+fa;
ans[i]=temp1%10+'0';
fa=temp1/10;
i--;
}
ans[p]='\0';
intpart+=fa;
cout<<intpart<<"."<<ans<<endl;
}
/*
5 10 7 80 50 40 2
26.71
*/