蓝桥杯试题 算法训练 猴子吃包子——大整数操作思想

蓝桥杯试题 算法训练 猴子吃包子

题目
资源限制
时间限制: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
*/


猜你喜欢

转载自blog.csdn.net/Andy_ss/article/details/107454328
今日推荐