zoukankan      html  css  js  c++  java
  • Project Euler 1-25

    A. Multiples of 3 and 5

    大水题,计算出below n内是3,5倍数的总和

    数据较大,只能用求和公式

    #include <iostream>
    #include <cstdio>
    typedef long long ll;
    using namespace std;
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            ll sum=0;
            ll p;
            p = (n-1)/3;
            sum += (1LL)*3*(p+1)*p/2;
            p = (n-1)/5;
            sum += (1LL)*5*(p+1)*p/2;
            p = (n-1)/15;
            sum -= (1LL)*15*(p+1)*p/2;
            cout<<sum<<endl;
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    View Code

    B.Even Fibonacci numbers

    求出n以内所有偶数的总和

    所有偶数都是3个一循环出现,序列为0,2,8,34,144...

    发现规律E【i】 = 4*E【i-1】+E【i-2】

    打表计算

    #include <iostream>
    #include <cstdio>
    typedef long long  ll;
    using namespace std;
    const int MAXN = 1e3+100;
    const ll MAXNN = 4e16;
    
    ll a[MAXN];
    ll sum[MAXN];
    ll top;
    
    int main()
    {
        a[0] = 0;
        a[1] = 2;
        sum[0] = 0;
        sum[1] = 2;
        for(ll i=2;;i++){
            a[i] = 4*a[i-1]+a[i-2];
            top ++;
            sum[i] = sum[i-1]+a[i];
            //cout<<top<<endl;
            if(a[i]>MAXNN)break;
        }
        top+=2;
        //cout<<a[2]<<a[3]<<" "<<a[4]<<endl;
        int T;
        scanf("%d",&T);
        while(T--){
            ll n;
            scanf("%lld",&n);
            int l=0,r=top;
            while(l<r){
                int m = l+(r-l)/2;
                if(a[m]<=n)l = m+1;
                else r = m;
            }
    
            printf("%lld
    ",sum[l-1]);
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    View Code

     http://digi.tech.qq.com/a/20150526/008620.htm

    我发现这个fib时钟挺好玩的

    时钟:红色+蓝色

    分钟:(绿色+蓝色)*5

    C. Largest prime factor

    求最大质因子

    prime打表,昨天打了bc,去求了最大因子,呵呵

    #include <iostream>
    #include <cstdio>
    typedef long long  ll;
    using namespace std;
    const int MAXN = 1e7+1000;
    //const ll MAXNN = 4e16;
    
    int visit[MAXN];
    ll p[MAXN];
    ll cnt;
    
    void isprime(){
        cnt = 0;
        for(ll i=2;i<MAXN;i++){
            if(!visit[i]){
                p[cnt++] = i;
                for(ll j=i*2;j<MAXN;j+=i){
                    visit[j] = 1;
                }
            }
        }
    }
    
    int main()
    {
        isprime();
        //cout<<p[1]<<endl;
        //cout<<p[2]<<endl;
        int T;
        scanf("%d",&T);
        while(T--){
            ll n;
            scanf("%lld",&n);
           // cout<<n<<endl;
            ll mmax = -1;
            for(ll i=0;i<cnt;i++){
                if(n%p[i]==0){
                    mmax = max(mmax,p[i]);
                    while(n%p[i]==0)n/=p[i];
                }
            }
            if(n>1){
                mmax = max(mmax,n);
            }
            cout<<mmax<<endl;
           // cout<<n<<endl;
    
        }
    
        return 0;
    }
    View Code

     

    H.Largest product in a series

    求k个连续序列最大值

    遍历的时候考虑前一个序列的第一个值是否为0

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <string>
    using namespace std;
    
    const int MAXN = 1e3+100;
    char ts[MAXN];
    
    int main(){
    
        int T;
        scanf("%d",&T);
        while(T--){
            int n,k;
            scanf("%d%d",&n,&k);
            scanf("%s",ts);
            int len = strlen(ts);
            int mmax=1;
            for(int i=0;i<k;i++)mmax *= (ts[i]-'0');
            int pre = mmax;
            //cout<<pre<<endl;
    
            for(int i=k;i<len;i++){
                //pre = pre/(ts[i-k]-'0')*(ts[i]-'0');
                if(ts[i-k]-'0'==0){
                   pre = 1;
                   int s = i-k+1;
                   for(int j=1;j<=k;j++){
                        pre *= (ts[s++]-'0');
                   }
                }else{
                    pre = pre*(ts[i]-'0')/(ts[i-k]-'0');
                }
                mmax = max(mmax,pre);
                //cout<<pre<<endl;
            }
            cout<<mmax<<endl;
        }
        return 0;
    }
    View Code

    I.Special Pythagorean triplet

    求构成勾股数的abc,乘积最大

    一眼看成求最小,测试数据能过,又傻逼了,改了一个小时看不出,差点要哭

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    typedef long long ll;
    using namespace std;
    
    
    const ll MAXN = 3e3+100;
    ll p[MAXN];
    
    int main()
    {
        //memset(p,-1,sizeof p);
        for(int i=1;i<MAXN/3;i++){
            for(int j=i+1;j<MAXN/2;j++){
                ll t = (1LL)*i*i + (1LL)*j*j;
                ll x = sqrt(t);
                if(t==x*x&&j<x&&i+j+x<MAXN){
                    if(p[i+j+x]==0)
                        p[i+j+x] = (1LL)*i*j*x;
                    else
                        p[i+j+x] = max(p[i+j+x],(1LL)*i*j*x);
                }
            }
        }
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            if(p[n]==0){
                cout<<-1<<endl;
                continue;
            }
            cout<<p[n]<<endl;
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    View Code

    L.Highly divisible triangular number

    这个挺坑的,反正思路挺清晰的,n的所有因子总数是 (1+a1)*(1+a2)*(1+a3)...(ai为n的质因子)

    至于为什么坑了那么久,就是因为打表的时候,我数组我不敢开太大,orz

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    
    typedef long long ll;
    
    using namespace std;
    
    const int MAXN = 1e4;
    const int MAXNN = 1e6;
    int vis[MAXN];
    int p[MAXN];
    int cnt;
    ll s[MAXNN];
    ll num[MAXNN];
    int top;
    
    void isprime(){
        cnt= 0;
        for(int i=2;i<MAXN;i++){
            if(!vis[i]){
                p[cnt++] = i;
                for(int j=2*i;j<MAXN;j+=i){
                    vis[j] = 1;
                }
            }
        }
    }
    
    int main()
    {
        isprime();
        top = 1;
        for(int i=1;i<MAXNN;i++)s[i] = s[i-1]+i;
        //cout<<s[MAXNN-1]<<endl;
        for(int i=1;i<MAXNN;i++){
            ll t = s[i];
            ll k = 0;
            ll sum=1;
            for(int j=0;j<cnt&&p[j]<=sqrt(t);j++){
                k=0;
                if(t%p[j]==0){
                    while(t%p[j]==0){
                        t/=p[j];
                        k++;
                    }
                    sum *= (k+1);
                }
            }
            if(t>1)sum *= 2;
            num[i] = sum;
            top++;
            if(sum>1000){
                break;
    
            }
            //cout<<sum<<endl;
        }
       // cout<<top<<endl;
        //cout<<num[top-1]<<endl;
        //cout<<s[top-1]<<endl;
    
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            ll ans=-1;
            for(int i=1;i<=top;i++){
                if(num[i]>n){
                    ans = s[i];
                    //cout<<i<<endl;
                    break;
                }
            }
            cout<<ans<<endl;
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    View Code

    M.Large sum

    大数模板

    http://blog.csdn.net/vsooda/article/details/8543351

    http://blog.csdn.net/y990041769/article/details/20116995

    这些模板都没负数操作的样子。。。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    
    using namespace std;
    
    string sum(string s1,string s2)
    {
        if(s1.length()<s2.length())
        {
            string temp=s1;
            s1=s2;
            s2=temp;
        }
        int i,j;
        for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--)
        {
            s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));   //注意细节
            if(s1[i]-'0'>=10)
            {
                s1[i]=char((s1[i]-'0')%10+'0');
                if(i) s1[i-1]++;
                else s1='1'+s1;
            }
        }
        return s1;
    }
    
    
    int main()
    {
        int n;
        scanf("%d",&n);
        string ts1;
        cin>>ts1;
        for(int i=1;i<n;i++){
            string ts2;
            cin>>ts2;
            ts1 = sum(ts1,ts2);
        }
        for(int i=0;i<10;i++)cout<<ts1[i];
        cout<<endl;
        //cout << "Hello world!" << endl;
        return 0;
    }
    View Code

    N.Longest Collatz sequence

    这题很坑

    n可能大于int了(奇数为3*n+1),所以这就要开longlong

    一天都不知道错在哪里

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    using namespace std;
    
    const int MAXN = 5e6+10;
    typedef long long ll;
    int a[MAXN],b[MAXN];
    
    int dfs(ll x){
        if(x<MAXN&&a[x]){
            return a[x];
        }
        int sum = 0;
        if(x%2==0){
            sum = dfs(x/2)+1;
        }else{
            sum = dfs(x*3+1)+1;
        }
        if(x<MAXN)a[x] = sum;
        return sum;
    }
    
    int main()
    {
        a[1]=b[1]=1;
        int mmax = -1;
        int pre = 1;
    
        for(int i=2;i<MAXN;i++){
            if(!a[i])
                a[i] = dfs(i);
            if(mmax<=a[i]){
                pre = i;
                mmax = a[i];
            }
            b[i] = pre;
        }
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            printf("%d
    ",b[n]);
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    View Code

     

    O.Lattice paths

    简单dp

    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    const ll mod = 1e9+7;
    const int MAXN = 5e2+10;
    
    ll dp[MAXN][MAXN];
    
    int main(){
       for(int i=1;i<MAXN;i++){
        for(int j=1;j<MAXN;j++){
            if(j==1&&i==1)dp[i][j] = 1;
            else
                dp[i][j] = dp[i-1][j]+dp[i][j-1];
                dp[i][j] %= mod;
            }
        }
        int T;
        scanf("%d",&T);
        while(T--){
            int n,m;
            scanf("%d%d",&n,&m);
            cout<<dp[n+1][m+1]<<endl;
        }
    }
    View Code

    P.Power digit sum

    字符串操作

    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    const ll mod = 1e9+7;
    const int MAXN = 1e4+100;
    
    string ts = "1";
    
    ll a[MAXN];
    
    int main(){
        for(int i=1;i<MAXN;i++){
            int len = ts.length();
            int flag = 0;
            ll sum = 0;
            for(int j=len-1;j>=0;j--){
                int t = ts[j]-'0';
                t = t*2+flag;
                ts[j] = char(t%10+'0');
                flag = t/10;
                sum += t%10;
            }
            if(flag){
                ts = "1"+ts;
                sum += 1;
            }
            //cout<<ts<<endl;
            a[i] = sum;
        }
        cout<<ts.length()<<endl;
        cout<<ts<<endl;
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            cout<<a[n]<<endl;
        }
    }
    View Code

     R.Maximum path sum I

    简单dp

    S.Counting Sundays

    计算任意任意区间每月第一天为周七的个数

    和省赛一题一模一样,不过好像是求周一的个数,然后我也想当然了,然后第二组测试数据直接出不来。。。

    不过学了一个很有用的计算任意时间为周几的 蔡勒公式

    http://blog.csdn.net/kumxp/article/details/5185309

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    typedef long long ll;
    
    /*计算任何日期为周几模板*/
    int fun(int x,int y,int z){
        if(y<3){
            x-=1;
            y+=12;
        }
        int a = x/100,b = x-100*a;
        int w = a/4 - 2*a+b+b/4+(13*(y+1)/5)+z-1;
        w = (w%7+7)%7;
        return w;
    }
    
    int main()
    {
        /*for(int i=1;i<13;i++){
            cout<<fun(2016,i,1)<<" ";
        }
        cout<<endl;*/
        int T;
        scanf("%d",&T);
        while(T--){
            ll tx1;int x1,y1,z1;
            ll tx2;int x2,y2,z2;
            scanf("%lld%d%d",&tx1,&y1,&z1);
            scanf("%lld%d%d",&tx2,&y2,&z2);
            x1 = (tx1-1900)%400+1900;
            x2 = (tx2-tx1)+x1;
            int ans = 0;
            for(int i=x1;i<=x2;i++){
                int ret = 0;
                int s = 1,e = 13;
                if(i==x1){
                    s = y1;
                    if(z1>1)s++;
                }if(i==x2){
                    e = y2+1;
                }
                for(int j=s;j<e;j++){
                    if(fun(i,j,1)==0)ret++;
                }
                //cout<<ret<<endl;
                ans += ret;
            }
           cout<<ans<<endl;
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    View Code

    T.Factorial digit sum

    继续套大数相乘模板

    U.Amicable numbers

    打表的时候注意是否会超出得到的数字是否会超出数组范围

    第二次犯这个错误了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1e5+1000;
    int a[MAXN];
    ll b[MAXN];
    int main()
    {
        //ll sum = 0;
        for(int i=1;i<MAXN;i++){
            int t = i;
            ll cnt = 0;
            for(int j=2;j<=sqrt(t);j++){
                if(t%j==0){
                    cnt += j;
                    if(j*j!=t)cnt+= t/j;
    
                }
            }
            cnt++;
            b[i] = cnt;
            if(cnt<i&&b[cnt]==i){a[i] = a[cnt] = 1;}
            else if(cnt>MAXN){
                ll k = 0;
                for(int j=2;j<=sqrt(k);j++){
                    if(cnt%j==0){
                        k += j;
                        if(j*j!=cnt)k+= cnt/j;
                    }
                }
                k++;
                if(cnt==k)a[i] = 1;
            }
            //cout<<sum<<endl;
        }
        //cout<<b[MAXN-20]<<endl;
    
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            ll ret = 0;
            for(int i=1;i<=n;i++){
                if(a[i])ret+= i;
            }
            cout<<ret<<endl;
        }
        return 0;
    }
    View Code

    X.Lexicographic permutations

    粗略学习了康托展开

    排列组合好像非常有用的样子

    http://www.cnblogs.com/xianglan/archive/2011/03/07/1976431.html

    http://blog.csdn.net/zhongkeli/article/details/6966805

    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    typedef long long ll;
    ll fac[20];
    int sg[20];
    
    
    int main(){
        ll mult = 1;
        for(int i=1;i<13;i++){
            mult *= i;
            fac[12-i] = mult;
        }
        int T;
        string ts;
        scanf("%d",&T);
        while(T--){
            ts = "abcdefghijklm";
            memset(sg,0,sizeof sg);
            ll n;
            scanf("%lld",&n);
            n--;
            for(int i=0;i<12;i++){
                sg[i] = n/fac[i];
                n -= sg[i]*fac[i];
            }
            /*for(int i=0;i<12;i++){
                cout<<sg[i]<<" ";
            }
            cout<<endl;*/
            for(int i=0;i<12;i++){
                swap(ts[i],ts[i+sg[i]]);
                sort(ts.begin()+i+1,ts.end());
            }
            cout<<ts<<endl;
         }
    }
    View Code

    Y.N-digit Fibonacci number

    求第一次出现5000-digit fibonacci的下标

    这题应该能用字符串的大数操作的样子

    学习了一种公式的方法

    fib数列如果n较大时,满足an/an+1 = 0.618:1

    则an*phi = an,phi=(1+sqrt(5))/2

    ox  = (1-sqrt(5))/2

    可以推出an的通式 an = 1/(sqrt(5))*(phi-ox)^n

    则len_dig = (int)(nlog10(phi)-log10(5)/2+1)

    呵呵,继续学习了fib

    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    typedef long long ll;
    const int MAXN = 5e3+10;
    const int MAXNN = 3e4+100;
    double golden = (1+sqrt(5))/2;
    int a[MAXN];
    int len_fib(ll n){
        return (int)(n*log10(golden) - log10(5)/2+1);
    }
    
    
    int main(){
        //cout<<len_fib(17)<<endl;
        //ll k = 0;
        a[1] = 1;
        for(int i=2;i<MAXN;i++){
            int l = 1,r = MAXNN;
            while(l<r){
                int m = l+(r-l)/2;
                if(len_fib(m)<i)l = m+1;
                else r = m;
            }
            a[i] = l;
        }
        /*cout<<a[2]<<endl;
        cout<<a[3]<<endl;
        cout<<a[5000]<<endl;
        cout<<k<<endl;*/
        int T;
        scanf("%d",&T);
        while(T--){
            int n;
            scanf("%d",&n);
            cout<<a[n]<<endl;
        }
        return 0;
    }
    View Code
    在一个谎言的国度,沉默就是英雄
  • 相关阅读:
    (原)Lazarus 异构平台下多层架构思路、DataSet转换核心代码
    (学)新版动态表单研发,阶段成果3
    (学) 如何将 Oracle 序列 重置 清零 How to reset an Oracle sequence
    (学)XtraReport WebService Print 报错
    (原)三星 i6410 刷机 短信 无法 保存 解决 办法
    (原) Devexpress 汉化包 制作工具、测试程序
    linux下网络配置
    apache自带ab.exe小工具使用小结
    Yii::app()用法小结
    PDO使用小结
  • 原文地址:https://www.cnblogs.com/EdsonLin/p/5702123.html
Copyright © 2011-2022 走看看