为什么感觉6-10题比1-5题暴力了好多,没什么好的可改进点-_-!!!
第6题
这个题求 (∑ni=1i)2−(∑ni=1i2) ,是 O(1) 的。
int main(){
long long ans=0,n=100;
ans=n*(n+1)/2;
ans*=ans;
ans-=n*(n+1)*(2*n+1)/6;
cout<<ans<<endl;
return 0;
}
此外:
∑ni=1i3=(∑ni=1i)2=n∗(n+1)/2
第7题
题目来源ProjectEuler
这个题是求第10001个素数。
关于小于N的素数的个数,有这么一个估计公式:
π(N)≈Nln(N)
详情可参考维基百科
考虑到
lnx≈lnxlnx
所以第10001个素数大小大概为
10001∗ln(10001)≈132878
,跟答案在一个数量级内。
而求素数算法中,有一个近似线性时间(在
O(n)−O(nlogn)之间
)内求出所有小于n的素数的算法,叫线性筛,也叫欧拉筛。
int prime[10000000],cnt;
int num[10000000];
int main(){
cnt=0;int n=10000000-1;
for(int i=2;i<=n;i++){
if(num[i]==0) prime[++cnt]=i;
for (int j=1;j<=cnt&&i*prime[j]<=n;j++){
num[i*prime[j]]=1;
}
}
cout<<prime[10001]<<endl;
return 0;
}
大致思路是这样的,我们从2-n依次选择一个数
i
,若
因为每个合数
x
都可以表示为
复杂度
f(n)
计算方法为
O(n)<f(n)=∑ni=2min(π(i),ni)<∑ni=2ni≈nlnn
第8题
这个题是给你一千个数字,求最大的连续13个数字的积。
分析一下可以发现,如果这13个数字中有一个0,那么这个结果肯定不能要。
那么我们的策略就显然了,我们先令ans=0,记录一下当前的product是连续cnt个非零数字的积。那么当cnt==13的时候,我们将product除掉第一个数字,乘上现在这个数字,得到一个新的product,ans更新为product和ans的最大值;当cnt<13的时候,我们将product直接乘上当前这个数字,并且cnt++。在结束当前循环前,判断product是否为0,若product==0,则将cnt归零。
复杂度
O(n+len)
char s[1050];
int main(){
for (int i=0;i<20;i++){
scanf("%s",s+i*50);
}
int len=13;long long ans=0,product=1,cnt=0;
for(int i=0;i<1000;i++){
if (cnt<len){
product*=(s[i]-'0');
cnt++;
}
else{
product/=(s[i-len]-'0');
product*=(s[i]-'0');
ans=max(ans,product);
}
if (product==0){
product=1;
cnt=0;
}
}
cout<<ans<<endl;
return 0;
}
第9题
这个是求a,b,c,满足
a2+b2=c2
且
a+b+c=1000
枚举a,b,令c=1000-a-b,判断
a2+b2=c2
是否成立,成立则输出并退出程序。
因为
c>max(a,b)
所以a,b只需要枚举到500就可以了。
输出a,b,c可以看到
2002+3752=4252
int main(){
for (int a=1;a<500;a++){
for (int b=1;b<500;b++){
int c=1000-a-b;
if (a*a+b*b==c*c){
printf("%d %d %d %d\n",a,b,c,a*b*c);
return 0;
}
}
}
}
第10题
这里是求所有小于2,000,000的素数的和,使用第7题里面的线性筛,求和即可。
int prime[10000000],cnt;
int num[10000000];
int main(){
cnt=0;int n=10000000-1;
for(int i=2;i<=n;i++){
if(num[i]==0) prime[++cnt]=i;
for (int j=1;j<=cnt&&i*prime[j]<=n;j++){
num[i*prime[j]]=1;
}
}
long long ans=0;
for (int i=1;i<=cnt;i++){
if (prime[i]<2000000) ans+=prime[i];
else break;
}
cout<<ans<<endl;
return 0;
}