给n个数(0<=ai<=1e18),求n个数的乘积,如果超过1e18则输出-1
这个题考的是对数据类型溢出的处理。我们知道数据类型的范围是一个循环,
0到最大值,超过最大值,变为最小值,然后最小值到0.如果这个题是考和的话,
我们就可以利用这一点,来判断是否溢出。但是考的是积,则需要特殊去处理。
1.判断是否有0的值,如果有,乘积为0
2.前一个乘积的大小为ans,当前为temp,我们需要判断ans*temp>INF
则去判断INF/temp
#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;
}
给定一个整数a(0<=x<=1e15)和一个10以下的有两位小数的浮点数b,求a*b;
本题考的是浮点数精度问题 ,在计算机中,小数转化为二进制会失精。
解决:
1.用字符串处理浮点数
2.竟然要失去精度,那么可以多加一点小数,题目说要舍去小数的。
#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;
}
#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;
}
给定一个正整数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;
}