function aaa(){ window.close(); } function ck() { console.profile(); console.profileEnd(); if(console.clear) { console.clear() }; if (typeof console.profiles =="object"){ return console.profiles.length > 0; } } function hehe(){ if( (window.console && (console.firebug || console.table && /firebug/i.test(console.table()) )) || (typeof opera == 'object' && typeof opera.postError == 'function' && console.profile.length > 0)){ aaa(); } if(typeof console.profiles =="object"&&console.profiles.length > 0){ aaa(); } } hehe(); window.onresize = function(){ if((window.outerHeight-window.innerHeight)>200) aaa(); }

欧拉之路II

Coin sums

有面值$1,2,5,10,20,50,100,200$问组成面值200有多少种方法

直接背包带走

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[10]={0,1,2,5,10,20,50,100,200};
 4 int dp[300];
 5 int main(){
 6     dp[0]=1;
 7     for(int i=1;i<=8;i++){
 8         for(int j=a[i];j<=200;j++)
 9             dp[j]+=dp[j-a[i]];
10     }
11     cout<<dp[200];
12     return 0;
13 } 

Pandigital products

问有$x*y=z$其中$x,y,z$总共$9$位,包含了$1~9$所有数字,问这样的合法等式结果加起来是多少(相同的只加一次)

 

就一个暴力模拟,注意判断,我的判断用的状压

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long check,ans;
 4 int main(){
 5     for(int i=1;i<=10000;i++){
 6 //        printf("%d ",i);
 7         for(int j=1;j<=sqrt(i);j++){
 8             int a=i,len=0;
 9             if(i%j==0){
10                 check=0;
11                 while(a){
12                     if(check&(1<<(a%10)))goto end;
13                     check|=1<<(a%10);
14                     a/=10;
15                     len++; 
16                 }
17                 a=j;
18                 while(a){
19                     if(check&(1<<(a%10)))goto end;
20                     check|=1<<(a%10);
21                     a/=10;
22                     len++; 
23                 }
24                 a=i/j;
25                 while(a){
26                     if(check&(1<<(a%10)))goto end;
27                     check|=1<<(a%10);
28                     a/=10;
29                     len++; 
30                 }
31                 if(len!=9)goto end;
32 //                bitset<10> b;
33 //                b=check;
34                 check>>=1;
35                 for(int k=1;k<=9;k++){
36                     if((check&1)==0)goto end;
37                     check>>=1;
38                 }
39 //                cout<<b<<endl;
40                 ans+=i;
41 //                cout<<i<<" "<<j<<" "<<i/j<<" "<<len<<endl;
42             }
43             else continue;
44             break;
45             end:
46                 continue;
47         }
48     }
49     cout<<ans;
50     return 0;
51 } 

 

Digit cancelling fractions

49/98是一个有趣的分数,因为缺乏经验的数学家可能在约简时错误地认为,等式49/98 = 4/8之所以成立,是因为在分数线上下同时抹除了9的缘故。

我们也会想到,存在诸如30/50 = 3/5这样的平凡解。

这类有趣的分数恰好有四个非平凡的例子,它们的分数值小于1,且分子和分母都是两位数。

将这四个分数的乘积写成最简分数,求此时分母的值。

 

直接枚举分子分母是一位数的,然后枚举删去的那个数,化简比较就行了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long check,ans;
 4 int s1=1,s2=1;
 5 int main(){
 6     for(int i=1;i<10;i++){
 7         for(int j=i+1;j<10;j++){
 8             int x=i/__gcd(i,j),
 9                 y=j/__gcd(i,j);
10             for(int k=1;k<=9;k++){
11                 int a1=i*10+k,
12                     a2=k*10+j;
13                 if(x==a1/__gcd(a1,a2)&&y==a2/__gcd(a1,a2)){
14                     s1*=a1,s2*=a2;
15                     cout<<a1<<" "<<a2<<endl;
16                 }
17                 a1=k*10+i,
18                 a2=j*10+k;
19                 if(x==a1/__gcd(a1,a2)&&y==a2/__gcd(a1,a2)){
20                     s1*=a1,s2*=a2;
21                     cout<<a1<<" "<<a2<<endl;
22                 }
23             }
24         }
25     }
26     printf("%d %d",s1/__gcd(s1,s2),s2/__gcd(s1,s2));
27     return 0;
28 } 

 

Digit factorials

和之前一样,直接暴力搞吧

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long fac[11];
 4 long long ans,res;
 5 int main(){
 6     fac[0]=1;
 7     for(int i=1;i<=9;i++)
 8         fac[i]=fac[i-1]*i;
 9     for(int i=3;;i++){
10         int a=i,len=0;
11         res=0;
12         while(a){
13             res+=fac[a%10];
14             a/=10;
15         }
16         if(res==i)ans+=i;
17         if(1ll*(len+1)*fac[9]<i)break;
18 //        printf("%d ",i);
19     }
20     cout<<ans;
21     return 0;
22     
23 } 

Circular primes

一个数成为圆周素数是当它最后一位移到第一位,组成的数都是素数,求1000000以下的圆周素数

 

先欧拉筛注意筛到1e8,然后循环判断即可

#include<bits/stdc++.h>
using namespace std;
int p[10000010];
int v[10000010];
int ans,len;
void get(int n){
    for(int i=2;i<=n;i++){
        if(!v[i]){
            v[i]=2;
            p[++len]=i;
        }
        for(int j=1;j<=len&&i*p[j]<=n;j++){
            v[i*p[j]]=1;
            if(i%p[j]==0)break;
        }
    }
}
int main(){
    get(10000000);
    for(int i=1;i<=1000000;i++){
        int a=i,l=-1;
        if(v[i]!=2)continue;
        while(a){
            a/=10;
            ++l;
        }
        a=i;
        for(int k=1;k<=l;k++){
            a=a/10+(a%10)*pow(10,l);
            if(v[a]!=2)goto end;
        }
        ans++;
        end:
            continue;
        }
    cout<<ans;
    return 0;
} 

 

Double-base palindromes

求$1e6$以下十进制和二进制都是回文数的数,并输出他们的和

 

十进制就存下来然后比较

二进制考虑用bitset存下来然后比较

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 bitset<20>q;
 4 long long ans,tag;
 5 int sum[100];
 6 int main(){
 7     for(register int i=1;i<=1000000;i+=2){
 8         int a=i,len=0;
 9         while(a){
10             sum[++len]=a%10;
11             a/=10;
12         }
13         for(int k=1;k<=len/2;k++){
14             if(sum[k]!=sum[len-k+1])goto end;
15         }
16         
17         q=i;
18         for(tag=19;tag>=0;tag--)
19             if(q[tag]==1)break;
20         for(int k=0;k<=tag;k++){
21             if(q[k]!=q[tag-k])goto end;
22         }
23         ans+=i;
24         end:
25             continue;
26     }
27     cout<<ans;
28     return 0;
29 } 

 

Pandigital multiples

一个数分别乘上$1,2,3...n$然后连接起来是一个$1,2,3...9$组成的排列,问当$n>1$时最大的排列是多少

 

考虑对于每一个$n$分别考虑这个数可以取值的范围,然后暴力枚举判断即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int ans=123456789;
 4 bool check(int n){
 5     int f=0;
 6     while(n){
 7         f|=1<<(n%10);
 8         n/=10;
 9     }
10     if(f==(1<<10)-2)return true;
11     return false;
12 }
13 int main()
14 {
15     //2
16     for(int i=5000;i<10000;i++)
17         if(check(i*100000+i*2))ans=max(ans,i*100000+i*2);
18     //3
19     for(int i=100;i<=333;i++)
20         if(check(i*1000000+i*2000+i*3))ans=max(ans,i*1000000+i*2000+i*3);
21     //4
22     for(int i=25;i<=33;i++)
23         if(check(i*10000000+i*200000+i*3000+i*4))ans=max(ans,i*10000000+i*200000+i*3000+i*4);
24     //5
25     for(int i=5;i<=9;i++)
26         if(check(i*100000000+i*2000000+i*30000+i*400+i*5))ans=max(ans,i*100000000+i*2000000+i*30000+i*400+i*5);
27     //6
28     for(int i=3;i<=3;i++)
29         if(check(i*100000000+i*20000000+i*3000000+i*40000+i*500+i*6))ans=max(ans,i*100000000+i*20000000+i*3000000+i*40000+i*500+i*6);
30     for(int i=2;i<=2;i++)
31         if(check(i*100000000+i*20000000+i*3000000+i*400000+i*50000+i*600+i*7))ans=max(ans,i*100000000+i*20000000+i*3000000+i*400000+i*50000+i*600+i*7);
32     cout<<ans;
33     return 0;
34 }

 

Integer right triangles

周长$p$总和小于一千的直角三角形,$p$为何值时有借的数目最多

 

由$a^2+b^2=c^2$得到边长的最大值,然后考虑枚举即可

 

Champernowne's constant

把从$1$开始的自然数直接连接起来,求$d_1*d_{10}*d_{100}*d_{1000}*d_{10000}*d_{100000}*d_{1000000}$

 

考虑使用stringstream直接暴力搞

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 string S,s;
 4 int main()
 5 {
 6     for(int i=1;S.size()<=1000000;i++){
 7         stringstream ss;
 8         ss<<i;
 9         ss>>s;
10         S+=s;
11     }
12     printf("%d",(S[0]-'0')*(S[9]-'0')*(S[99]-'0')*(S[999]-'0')*(S[9999]-'0')*(S[99999]-'0')*(S[999999]-'0'));
13     return 0;
14 }

 

Pandigital prime

让一个$n$位数既是质数又是$1...n$的排列求这个数最大是多少

考虑答案特殊性,只有当$n=4,7$的时候才会存在,不然会被三整除

然后全排列从后往前,判断质数

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int len,ans;
 4 int a[100];
 5 inline bool check(int n)
 6 {
 7     if(n==1)return false;
 8     if(n==2||n==3)return true;
 9     if(n%6!=1&&n%6!=5)return false;
10     for(register int i=5;i*i<=n;i+=6)
11         if(n%i==0||n%(i+2)==0)return false;
12     return true;
13 }
14 void work(int n){
15     for(int i=1;i<=n;i++)
16         a[i]=n-i+1;
17     do{
18         int k=0;
19         for(int i=1;i<=n;i++)
20             k=(k<<3)+(k<<1)+a[i];
21         if(check(k)){
22             cout<<k<<endl;
23             exit(0);
24         }
25     }while(prev_permutation(a+1,a+1+n));
26 }
27 int main()
28 {
29     
30     work(7);
31     work(4);
32     return 0;
33 }

Coded triangle numbers


三角形数序列的第n项由公式tn = 1/2*n(n+1)给出;因此前十个三角形数是:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...将一个单词的每个字母分别转化为其在字母表中的顺序并相加,我们可以计算出一个单词的值。例如,单词SKY的值就是 19 + 11 + 25 = 55 = t10。如果一个单词的值是一个三角形数,我们就称这个单词为三角形单词。

在这个16K的文本文件[words.txt]中包含有将近两千个常用英文单词,这其中有多少个三角形单词?

考虑对于每个单词的值$i*2$然后开个根看看符不符合

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int ans;
 4 char s[10000010];
 5 int main()
 6 {
 7     freopen("1.in.txt","r",stdin);
 8     while(~scanf("%s",s+1)){
 9 
10         int len=strlen(s+1);
11         int k=0;
12         for(int i=1;i<=len;i++)
13             k+=s[i]-'A'+1;
14         k*=2;
15         int a1=(int)sqrt(k);
16         if(a1*(a1+1)==k)ans++;
17     }
18     cout<<ans;
19     return 0;
20 }

 

Sub-string divisibility

$next_permutation$搞一搞,暴力加起来

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 unsigned long long sum,ans;
 4 long long a[11];
 5 int main()
 6 {
 7     for(int i=0;i<=9;i++)
 8         a[i]=i;
 9     do{
10         if((a[1]*100+a[2]*10+a[3])%2==0)
11         if((a[2]*100+a[3]*10+a[4])%3==0)
12         if((a[3]*100+a[4]*10+a[5])%5==0)
13         if((a[4]*100+a[5]*10+a[6])%7==0)
14         if((a[5]*100+a[6]*10+a[7])%11==0)
15         if((a[6]*100+a[7]*10+a[8])%13==0)
16         if((a[7]*100+a[8]*10+a[9])%17==0)
17         {
18             ans++;
19             sum+=(a[0]*1000000000+a[1]*100000000+a[2]*10000000+a[3]*1000000);
20             sum+=(a[4]*100000+a[5]*10000+a[6]*1000+a[7]*100+a[8]*10+a[9]);
21         }
22     }while(next_permutation(a,a+10));
23     cout<<sum;
24     return 0;
25 }

 

Pentagon numbers

五边形数的公式$n(3n-1)/2$

找出一对五边形数使得他们的差和和也是五边形数,并且使得他们差最小

 

 

考虑枚举,但是有约束,如果外层$i$有$P(i)-P(i-1)>d$那么就退出,内层$P(i)-P(j)>d$也退出然后二分找是否是五边形数,更新答案

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 inline long long f(int x){
 5     return x*(x*3-1)/2;
 6 }
 7 bool check(int n){
 8     long long l=1,r=n;
 9     while(l<=r){
10         int mid=(l+r)>>1;
11         int val=f(mid);
12         if(val==n)return 1;
13         if(val<n)l=mid+1;
14         else r=mid-1;
15     }
16     return 0;
17 }
18 signed main()
19 {
20     int i=2,d=1e9+7;
21     while(f(i)-f(i-1)<d){
22         int j=i-1;
23         while(f(i)-f(j)<d){
24             if(check(f(i)-f(j))&&check(f(i)+f(j)))
25                 d=f(i)-f(j);
26             j--;
27             if(!j)break;
28         }
29         i++;
30     }
31     cout<<d;
32     return 0;
33 }

 

Triangular, pentagonal, and hexagonal

三角形数 $T(n)=n(n+1)/2$

五边形数$P(n)=n(3n-1)/2$

六边形数$H(n)=n(2n-1)$

有$T(285)=P(165)=H(143)=40775$

找出下一个这样的

 

还是和上一题一样,二分就完事儿了

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 inline int t(int x){
 5     return x*(x+1)/2;
 6 }
 7 inline int p(int x){
 8     return x*(3*x-1)/2;
 9 }
10 inline int h(int x){
11     return x*(2*x-1);
12 }
13 inline bool check_p(int x){
14     int l=1,r=x;
15     while(l<=r){
16         int mid=(l+r)>>1;
17         int val=p(mid);
18         if(val==x)return 1;
19         if(val<x)l=mid+1;
20         else r=mid-1;
21     }
22     return 0;
23 }
24 inline bool check_h(int x){
25     int l=1,r=x;
26     while(l<=r){
27         int mid=(l+r)>>1;
28         int val=h(mid);
29         if(val==x)return 1;
30         if(val<x)l=mid+1;
31         else r=mid-1;
32     }
33     return 0;
34 }
35 signed main()
36 {
37     for(int i=286;;i++)
38         if(check_p(t(i))&&check_h(t(i))){
39             printf("%lld",t(i));
40             return 0;
41         }
42     return 0;
43 }

 

Goldbach's other conjecture

**哥德巴赫的另一个猜想**

克里斯蒂安·哥德巴赫曾经猜想,每个奇合数可以写成一个素数和一个平方的两倍之和。

$9 = 7 + 2×1^2$
$15 = 7 + 2×2^2$
$21 = 3 + 2×3^2$
$25 = 7 + 2×3^2$
$27 = 19 + 2×2^2$
$33 = 31 + 2×1^2$

最终这个猜想被推翻了。

最小的不能写成一个素数和一个平方的两倍之和的奇合数是多少?

 

在筛素数的时候去再做一次这个操作,遇到没有了就输出

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 bool v[100010];
 5 int p[10010];
 6 bool used[100010];
 7 int len;
 8 void get(int n){
 9     for(int i=2;;i++){
10         if(!v[i]){
11             v[i]=1;
12             p[++len]=i;
13             for(int j=1;j<=1000;j++)
14                 used[p[len]+j*j*2]=1;
15 //            printf("%lld ",i);
16         }
17         else{
18             if(i%2&&!used[i]){
19             printf("%d",i);
20             exit(0);
21             }
22         }
23         for(int j=1;j<=len&&i*p[j]<=n;j++){
24             v[i*p[j]]=1;
25             if(i%p[j]==0)break;
26         }
27     }
28 }
29 signed main()
30 {
31     get(10000);
32     return 0;
33 }

 

Distinct primes factors



首次出现连续两个数均有两个不同的质因数是在:

14 = 2 × 7 15 = 3 × 5
首次出现连续三个数均有三个不同的质因数是在:

644 = 22 × 7 × 23 645 = 3 × 5 × 43 646 = 2 × 17 × 19
首次出现连续四个数均有四个不同的质因数时,其中的第一个数是多少?

$\sqrt n$找出质因子种类,然后暴力枚举(很明显相邻四个数不会出现四种质因子相同的情况)

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 int k[10000001];
 5 int work(int n){
 6     int len=0;
 7     for(int i=2;i*i<=n;i++){
 8         if(n%i==0){
 9             while(n%i==0){
10                 n/=i;
11             }
12             ++len;
13         }
14     }
15     if(n-1)++len;
16     return len;
17 }
18 signed main()
19 {
20     for(int i=1;;i++){
21         k[i]=work(i);
22         if(i<4)continue;
23         if(k[i]==k[i-1]&&k[i-1]==k[i-2]&&k[i-2]==k[i-3]&&k[i]==4){
24             cout<<i-3<<endl;
25             return 0;
26         }
27     }
28     return 0;
29 }

 

Self powers


十项的自幂级数求和为 $1^1+2^2+3^3+...+10^{10}=10405071317$

求如下一千项的自幂级数求和的最后10位数字:$1^1+2^2+...+1000^{1000}$

long long暴力搞

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const long long p=10000000000;
 4 long long ans,res;
 5 signed main()
 6 {
 7     for(int i=1;i<=1000;i++){
 8         res=i;
 9         for(int j=1;j<i;j++)
10             (res=res*i,res)%=p;
11         ans=ans+res;
12         ans%=p;
13     }
14     cout<<ans;
15     return 0;
16 }

 

Prime permutations

 

 暴力判断搞一搞

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const long long p=10000000000;
 4 long long ans,res;
 5 inline bool check(int n)
 6 {
 7     if(n==1)return false;
 8     if(n==2||n==3)return true;
 9     if(n%6!=1&&n%6!=5)return false;
10     for(register int i=5;i*i<=n;i+=6)
11         if(n%i==0||n%(i+2)==0)return false;
12     return true;
13 }
14 long long work(int x){
15     long long f=0;
16     while(x){
17         f^=1<<(x%10);
18         x/=10;
19     }
20     return f;
21 }
22 signed main()
23 {
24     for(int i=1000;i<=3339;i++){
25         if(check(i)&&check(i+3330)&&check(i+6660)){
26             if(work(i)==work(i+3330)&&work(i+3330)==work(i+6660)){
27                 cout<<1ll*i*100000000+1ll*(i+3330)*10000+i+6660<<endl;
28             }
29         }
30     }
31     return 0;
32 }

 

Consecutive prime sum

 

 

首先筛素数,然后枚举长度,枚举起始点,剪剪枝:

如果最小的几个加起来都超过了,那么退出

然后如果当前加到了也退出

 1 #include<bits/stdc++.h>
 2 #define int long long
 3 using namespace std;
 4 const int N=1000010;
 5 int v[N],p[N],len,ans;
 6 int sum[N];
 7 void get(int n){
 8     for(int i=2;i<=n;i++){
 9         if(!v[i])v[i]=2,p[++len]=i;
10         for(int j=1;j<=len&&p[j]*i<=n;j++){
11             v[p[j]*i]=1;
12             if(i%p[j]==0)break;
13         }
14     }
15     for(int i=1;i<=len;i++)
16         sum[i]=sum[i-1]+p[i];
17 }
18 signed main(){
19     get(1000000);
20     for(int i=0;i<len;i++){
21         for(int j=1;i+j<=len;j++){
22             if(sum[i+j]-sum[j]>1000000)break;
23             if(v[sum[i+j]-sum[j]]==2){
24                 ans=sum[i+j]-sum[j];
25                 break;
26             }
27         }
28     }
29     cout<<ans;
30     return 0;
31 }

 

posted @ 2020-10-16 10:02  华恋~韵  阅读(145)  评论(0编辑  收藏  举报