第46题
这个题求满足如下条件的最小的数x:
1.是奇数
2.是合数
3.不能表示为
x=p+2∗y2
,其中p为质数,y为正整数。
先筛出一个范围内的质数,比如1~100w,然后求其中的合数是否满足以上条件。
复杂度
O(nn√)
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000000;
int num[maxn+1]={1,1},prime[maxn+1],cnt;
int main(){
for (int i=2;i<=maxn;i++){
if (num[i]==0) prime[++cnt]=i;
for (int j=1;j<=cnt&&i*prime[j]<=maxn;j++){
num[i*prime[j]]=1;
}
}
for (int i=35;;i+=2){
if (num[i]==0) continue;
int boolean=0;
for (int j=1;2*j*j<=i;j++){
if (num[i-j*j*2]==0){
boolean=1;
break;
}
}
if (!boolean){
cout<<i<<endl;
return 0;
}
}
}
第47题
这个题求连续的4个数的第1个数,要求这4个数每个数都恰好有4个质因子。
依然筛出前100w的质数,然后求每个数因子的个数,保存为fact,增加一个临时变量x,记录连续的质因子个数为4的数的个数,如果当期fact=4,x++,否则x=0;
当x=4的时候,输出i-3;
#include<bits/stdc++.h>
using namespace std;
const int maxn=999999;
int prime[maxn+10],num[maxn+10],cnt;
int fact;
int main(){
num[1]=0;
for (int i=2;i<=maxn;i++){
if (num[i]==0) prime[++cnt]=i;
for (int j=1;j<=cnt&&i*prime[j]<=maxn;j++){
num[i*prime[j]]=1;
}
}
int x=0;
for (int i=1;i<=maxn;i++){
int tmp=i;
fact=0;
for (int j=1;prime[j]*prime[j]<=tmp;j++){
if (tmp%prime[j]==0) fact++;
while(tmp%prime[j]==0) tmp/=prime[j];
}
if (tmp!=1) fact++;
if (fact==4) x++;
else x=0;
if (x==4){
cout<<i-3<<endl;
return 0;
}
}
}
第48题
这个题求
∑1000i=1ii
,保留最后十位,即mod=10,000,000,000
由于unsigned long long只能保存大约1.8e19的整数,不利用高精度,无法直接使用快速幂求出结果。
但由于mod为
1010
,通过对快速幂的一个简单的修改,不需要高精度也可以求出结果。
(a∗b)%mod=(a∗(b/100000)%mod∗100000+a∗(b%100000))%mod
#include<bits/stdc++.h>
using namespace std;
const long long mod=10000000000;
long long fexp(long long x,long long y){
long long ans=1,tmp;
while(y){
if (y&1){
ans=ans*(x/100000)%mod*100000+ans*(x%100000);
ans=ans%mod;
}
x=x*(x/100000)%mod*100000+x*(x%100000);
x%=mod;
y>>=1;
}
return ans;
}
int main(){
long long n=1000;
long long ans=0;
for (long long i=1;i<=n;i++){
ans+=fexp(i,i);
ans%=mod;
}
cout<<ans<<endl;
return 0;
}
第49题
这个题求这样三个四位质数,其中这三个质数构成等差数列且是同一组数字的不同排列。
例如题中给出的1487,4817,8147是公差为3330的等差数列,且是质数,是1,4,7,8的三个排列。
题目中告诉我们还有一组这样的四位数,要求找出来并且从小到大将他们连成一个12位数。
思路是枚举四个数字,对其所有排列进行check
#include<bits/stdc++.h>
using namespace std;
int num[6];
int prime[10010],boolean[10010],cnt;
void check(){
int x[25],cnt=0;
for (int i=1;i<=24;i++){
int tmp=0;
for (int j=1;j<=4;j++){
tmp=tmp*10+num[j];
}
if (!boolean[tmp]&&tmp>=1000) x[++cnt]=tmp;
next_permutation(num+1,num+5);
}
for (int i=1;i<=cnt;i++){
for (int j=i+1;j<=cnt;j++){
if (x[j]==x[i]) continue;
for (int k=j+1;k<=cnt;k++){
if(x[k]+x[i]==x[j]+x[j])
cout<<x[i]<<x[j]<<x[k]<<endl;
}
}
}
}
int main(){
boolean[1]=1;
for (int i=2;i<=9999;i++){
if (!boolean[i]) prime[++cnt]=i;
for (int j=1;j<=cnt&&i*prime[j]<=9999;j++){
boolean[i*prime[j]]=true;
}
}
for (int i=0;i<=9;i++){
num[1]=i;
for (int j=i;j<=9;j++){
num[2]=j;
for (int k=j;k<=9;k++){
num[3]=k;
for (int l=k;l<=9;l++){
num[4]=l;
check();
}
}
}
}
return 0;
}
第50题
有一些质数可以表示为若干个连续质数的和,比如
41=2+3+5+7+11+13
题目要求找出小于100w的质数中,能表示为最多质数和的那个质数。
对于100w以内的所有质数,枚举起点,一直求和,直到和大于100w为止。中途记录最长长度即达成该长度的sum值。
由于连续的求和,sum与长度len的关系大约是
sum>len22
,所以复杂度大约为
O(nn√)
,实际上快大约1个数量级。
#include<bits/stdc++.h>
using namespace std;
const int n=1000000;
int num[n+1],prime[n+1],cnt;
int main(){
for (int i=2;i<=n;i++){
if (!num[i]) prime[++cnt]=i;
for (int j=1;j<=cnt&&i*prime[j]<=n;j++){
num[i*prime[j]]=1;
}
}
int maxx=0,ans,sta;
for (int i=1;i<=cnt;i++){
int sum=0;
for (int j=0;sum<n&&j+i<=cnt;j++){
sum+=prime[i+j];
if (maxx<j&&sum<n&&num[sum]==0){
maxx=j;ans=sum;sta=i;
}
}
}
cout<<ans<<endl;
return 0;
}