AtCoder Beginner Contest 169:BCD

B - Multiplication 2

题意

给n个数(0<=ai<=1e18),求n个数的乘积,如果超过1e18则输出-1

思路

这个题考的是对数据类型溢出的处理。我们知道数据类型的范围是一个循环,
0到最大值,超过最大值,变为最小值,然后最小值到0.如果这个题是考和的话,
我们就可以利用这一点,来判断是否溢出。但是考的是积,则需要特殊去处理。
1.判断是否有0的值,如果有,乘积为0
2.前一个乘积的大小为ans,当前为temp,我们需要判断ans*temp>INF
则去判断INF/temp

AC代码

#include
#include
#include
using namespace std;
typedef long long ll;
const long long INF=1e18;
int main(){
	int n;
	cin>>n;
	ll ans=1,temp;
	int flag=0;
	for(int i=0;i<n;i++){
		cin>>temp;
		if(temp==0){
			flag=1;
		}
		if(flag==1)	continue;
		if(INF/temp<ans)//将乘法变为除法来判断 
			flag=-1;
		ans*=temp;
	}
	if(flag==1)	puts("0");
	else if(flag==-1)	puts("-1");
	else	cout<<ans<<endl;
	return 0;
} 

C - Multiplication 3

题意

给定一个整数a(0<=x<=1e15)和一个10以下的有两位小数的浮点数b,求a*b;

思路

本题考的是浮点数精度问题 ,在计算机中,小数转化为二进制会失精。
解决:
1.用字符串处理浮点数
2.竟然要失去精度,那么可以多加一点小数,题目说要舍去小数的。

AC代码1

#include
#include
using namespace std;
int main(){
	long long a,b;
	char s[5];
	cin>>a>>s;
	b=100*(s[0]^'0')+10*(s[2]^'0')+(s[3]^'0');
	cout<<a*b/100<<endl;
	return 0;
}

AC代码2

#include
#include
using namespace std;
int main(){
	long long a;
	double b;
	cin>>a>>b;
	b=b*(100+0.1);
	a*=(int)b;
	cout<<a/100<<endl;
	return 0;
}

D - Div Game

题意

给定一个正整数n(1<=n<=1e12),
选择一个整数z;
1.z=p的e次方,p是素数
2.n%z==0;
3.z与先前操作中选取的数不同

思路

1.这个题我们不需要去判断除得是否为素数。
2.可以从2开始枚举到根号n,根号n到后面的数是除不尽的-->减少循环次数 O(根号n) 
3.每次除的就是当前最小的素数,因为每次除当前最小的素数时,把所有
时当前的素数的合数能除的都除了。
4.处理每次除以当前最小素数以及它的合数,这里用了一个很巧妙的方法,就是
把除以当前最小素数的指数找出来,然后判断由这个指数构成的有几个不同的数,
最终结果加上这几个数即可
5.循环必定以素数或者是1出来,判断一下最后一次是否是素数即可 

代码

#include
#include
using namespace std;
typedef long long ll;
int solve(int x){//计算以i为底,以x为指数一共有多少不同的值 
	int now=1,res=0;
	while(now<=x){
		x-=now;
		now++;
		res++;
	}
	return res;
}
int main(){
	ll n;
	int ans=0;
	cin>>n;
	for(ll i=2;i*i<=n;i++){
		if(n%i==0){
			int cnt=0;
			while(n%i==0){//计算以i为底的指数为多少 
				n/=i;
				cnt++;
			}
			ans+=solve(cnt);
		}
	}
	if(n!=1) ans++;
	cout<<ans<<endl;
	return 0;
}

你可能感兴趣的:(算法刷题库)