• 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
    在一个谎言的国度,沉默就是英雄
  • 相关阅读:
    Selenium Webdriver元素定位的八种常用方式【转】
    python学习笔记(3)函数、参数、变量、递归
    Python学习总结
    Webdriver API (二)
    Webdriver API (一)
    解决Selenium弹出新页面无法定位元素问题(Unable to locate element)
    selenium之 定位以及切换frame(iframe)
    第一篇博客
    自制DTU
    DTU软硬件方案
  • 原文地址:https://www.cnblogs.com/EdsonLin/p/5702123.html
Copyright © 2020-2023  润新知