• NOIP模拟7


    期望得分:100+100+20=220

    实际得分:100+95+20=215

    T1 洛谷 P1306 斐波那契公约数

    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    LL t[2][2],ans[2][2],r[2][2];
    const int mod=1e8;
    int gcd(int a,int b)
    {
        return !b ? a : gcd(b,a%b);
    }
    void mul(LL a[2][2],LL b[2][2])
    {
        memset(r,0,sizeof(r));
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                for(int k=0;k<2;k++)
                    r[i][j]+=a[i][k]*b[k][j],r[i][j]%=mod;
        for(int i=0;i<2;i++)
            for(int j=0;j<2;j++)
                a[i][j]=r[i][j];
    }
    int main()
    {
        int a,b;
        scanf("%d%d",&a,&b);
        int p=gcd(a,b);
        t[0][0]=t[0][1]=t[1][0]=1;;
        ans[0][0]=ans[0][1]=1;
        if(p==2 || p==1) { printf("1"); return 0; }
        p-=2;
        while(p)
        {
            if(p&1) mul(ans,t);
            mul(t,t); p>>=1;
        }
        printf("%lld",ans[0][0]);
    }
    View Code

    T2 51nod 1431 快乐排队

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1431

    贪心

    每个点每往上一步-1,每往下一步+1

    最上面肯定越大越好

    假设所有的点都到最上面

    按从大到小的顺序,取最大的作为第一个

    然后所有的点每往下移一步就+1

    所以从2开始枚举当前要放从上往下的第sum个,如果这个点+sum-1<=上一个,就放

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #define N 200001
    using namespace std;
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    int a[N];
    int main()
    {
        int n;
            read(n);
             for(int i=1;i<=n;i++) read(a[i]);
            for(int i=1;i<=n;i++) a[i]=i-n+a[i];
            sort(a+1,a+n+1,greater<int>());
            int last,sum=0;
            last=a[1],sum++;
            for(int i=2;i<=n;i++)
                if(a[i]+sum<=last) last=a[i]+sum,sum++;
            if(sum==n) printf("Happy");
            else printf("Sad");
    }
    View Code

    std 做法:

    a[i]+i,不变,排序去重

    T3 51nod 1693 水群

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1693

    x向i*x连边权为i的边

    只需要连素数

    经各种研究发现

    在<=1e6时,退格操作最多有4个,且只会用到前5个素数

    所以dp[i][0]表示 当前长度为i,上一步操作为退格

    dp[i][1]表示当前长度为i,上一步可以是任何操作

    #include<cstdio>
    #include<algorithm>
    #define N 1000001
    using namespace std;
    int p[5]={2,3,5,7,11};
    int dp[N][2];
    int dfs(int x,int y)
    {
        if(x==1) return 0;
        if(dp[x][y]) return dp[x][y];
        dp[x][y]=N;
        for(int i=0;i<5;i++) 
            if(!(x%p[i])) dp[x][y]=min(dp[x][y],dfs(x/p[i],1)+p[i]);
        if(!y) return dp[x][y];
    //    dp[x][0]=dp[x][1];
        for(int i=1;i<5;i++) dp[x][y]=min(dp[x][y],dfs(x+i,0)+i);
        return dp[x][y];
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        printf("%d",dfs(n,1));
    }
    View Code
  • 相关阅读:
    异常处理
    反射4中内置函数
    property装饰器与继承
    封装
    面向对象编程
    面向对象编程
    项目开发规范
    logging模块
    22. 一个题来探查对 字符串,指针,数组三方面的关联使用方面的概念是否清晰,分析下面三个printf打印什么?
    21. 让指针数组结尾带NULL,使遍历时不依靠计算整个数组大小就可以在结尾遍历结束
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7512125.html
Copyright © 2020-2023  润新知