第36题
这一题求的是小于1,000,000的所有数中,在十进制和二进制表示下都是回文数的数的和。
枚举每个数,检验即可,复杂度 O(nlogn)
另一种方法,可枚举前一半的位上的数字,然后将整个数加上去,由于这样产生的所有数都是结果的一部分,省去了许多冗余的运算,会更快一些。但是代码复杂度更高一些。
我使用的是第一种方法:
#include<bits/stdc++.h>
using namespace std;
bool check(int x){
int a[25]={
0};
int tmp=x,cnt=0;
while(tmp){
a[++cnt]=tmp%10;
tmp/=10;
}
for (int i=1;i<=cnt;i++){
if (a[i]!=a[cnt-i+1]) return false;
}
tmp=x;cnt=0;
while(tmp){
a[++cnt]=tmp&1;
tmp>>=1;
}
for (int i=1;i<=cnt;i++){
if (a[i]!=a[cnt-i+1]) return false;
}
return true;
}
int main(){
long long ans=0;
for (int i=1;i<1000000;i++){
if (check(i)) ans+=i;
}
cout<<ans<<endl;
return 0;
}
第37题
这一题是有所有这样素数的和:1.它不是一位数、2.它的所有前缀和后缀都是素数
题目中保证了结果只有11个素数的和,但没有指明最大值。只能尝试着利用线性筛求出1000w以内的所有素数,从小到大依次检查,直到检查出11个为止。
#include<bits/stdc++.h>
using namespace std;
const int maxn=10000000;
int prime[maxn+1],cnt;
int num[maxn+1];
bool check(int x){
for (int i=10;i/10<x;i*=10){
if (num[x%i]) return false;
}
while(x){
if (num[x]) return false;
x/=10;
}
return true;
}
int main(){
cnt=0;
num[1]=1;
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 n=0,ans=0;
for (int i=5;n<11;i++){
if (check(prime[i])){
n++;ans+=prime[i];
}
}
cout<<ans<<endl;
return 0;
}
第38题
对于1-9的全排列构成的所有数,有一部分数可以表示成 (x∗1)(x∗2)(x∗3)…(x∗n)¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯