zoukankan      html  css  js  c++  java
  • 2017.7.12 C组总结

    NO.1

    题目描述: n只蚂蚁以每秒1cm的速度在长为Lcm的竿子上爬行。当蚂蚁爬到竿子的端点时就会掉落。由于竿子太细,两只蚂蚁相遇时,它们不能交错通过,只能各自反向爬回去。对于每只蚂蚁,我们知道它距离竿子左端的距离xi,但不知道它当前的朝向。请计算各种情况当中,所有蚂蚁落下竿子所需的最短时间和最长时间。

    思路:这里写图片描述

    代码:

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    #define MAXN 50000+2
    int a[MAXN];
    int main()
    {
        freopen("t1.in","r",stdin);
        freopen("t1.out","w",stdout);
        int n,l;
        cin>>n>>l;
        int x=0,y=0,k;
        for (int i=1;i<=n;i++)
        {
            cin>>a[i];
            k=min(a[i],l-a[i]);if (x<k) x=k;
            k=max(a[i],l-a[i]);if (y<k) y=k;
        }
        cout<<x<<" "<<y<<endl;
        fclose(stdin);
        fclose(stdout);
        return 0;
    }

    NO.2

    题目描述:一个正整数一般可以分为几个互不相同的自然数的和,如3=1+2,4=1+3,5=1+4=2+3,6=1+5=2+4,…。现在你的任务是将指定的正整数n分解成m个(m>=1)互不相同的自然数的和,且使这些自然数的乘积最大。

    思路:可以从2开始,枚举2+3+…i小于等于n的最大值i
    剩下的值downto 加回去
    再高精求出值

    代码:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    int n,m,l,w,k[10001],a[10000],maxn=10000;
    void gaojin(int x)
    {
        int g=0,k=0;
        for (int i=maxn;i>=1;i--)
        {
            g=a[i]*x+k;
            a[i]=g%10;
            k=g/10;
        }
    }
    int main()
    {
        freopen("max.in","r",stdin);
        freopen("max.out","w",stdout);
        scanf("%d",&n);
        m=n;
        l=2;    
        if (n==4) 
        {
            printf("%d
    %d",n,n);
            return 0;
        }
        while (m>=l)
        {
            w++;
            k[w]=l;
            m-=l;
            l++;
        }
        if (m<=w) for (int i=m;i>=1;i--) k[w-i+1]++;
        else
        {
            for (int i=w;i>=1;i--) k[w-i+1]++;
            for (int i=m-w;i>=1;i--) k[w-i+1]++;
        }
        a[maxn]=1;
        for (int i=1;i<=w;i++) 
        {
            printf("%d ",k[i]);
            gaojin(k[i]);
        }
        printf("
    ");
        l=1;
        while (a[l]==0) l++;
        for (int i=l;i<=maxn;i++) printf("%d",a[i]);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }

    NO.3

    题目描述:一天,还是Famer KXP,他在与他的好朋友Famer John玩一个游戏,规则如下:KXP站在起点,桌子上放置着一排物品,每个物品都有它的质量和距离起点的位置。KXP的基础分=最远物品距离*2+拿的物品的质量和,最终分数=最远物品距离*2+拿的物品的质量和*Y(Y为该物品是第Y个被拿的)KXP想提前知道自己在拿X个物品时基础分最高时最终分数为多少,若在拿K个时有多种情况能达到最高基础分则只输出X小于K时的情况(即发现有多种情况就立即结束程序),希望你帮忙解决。(K不一定被询问)

    思路:贪心+堆维护
    先将询问1时,的终极分数是多少
    然后在每次询问,找到每次可以增加的最大值,再用堆维护

    NO.4

    题目描述:这种军队共有N个单位,一个接着一个排成一排,每个单位可以是士兵,或者是战车,这样的组合可以爆发出意想不到的强大战斗力;但有一点,两辆战车不能相邻,否则会发生剐蹭等不好的事故。刘邦希望知道这N个单位的军队都多少种不同的排列方法,以便在战场中随机应变。两种军队的排列方法是不同的,当且仅当某一个单位对应不同,如:第i位这种是士兵,那种是战车……

    思路:30%做法:搜索
    分两种情况,①当前为士兵(0),那么后面放什么都符合,dfs(dep+1,1)+dfs(dep+1,0)
    ②当前为战车(1),那么后面只能跟士兵,dfs(dep+1,0)
    30%代码:

    #include<cstdio>
    #include<iostream>
    int n;
    int dfs(int x,int y)
    {
        if (x>=n) return 1;
        if (y==0) return dfs(x+1,1)+dfs(x+1,0); 
        else return dfs(x+1,0);
    }
    using namespace std;
    int main()
    {
        freopen("siege.in","r",stdin);
        freopen("siege.out","w",stdout);
        scanf("%d",&n);
        printf("%d",dfs(1,0)+dfs(1,1));
        fclose(stdin);
        fclose(stdout);
    }

    70%做法:斐波那契数列
    由上得出 f[i][0]+f[i][1]=f[i-1][1]+f[i-1][0]+f[i-1][0]….①
    设g[i]为i长的序列排放的方案数
    ①转换得g[i-1]+f[i-1][0]
    =g[i-1]+f[i-2][1]+f[i-2][0]
    =g[i-1]+g[i-2]
    就是一个明显的斐波那契数列

    70%代码:

    #include<cstdio>
    #include<iostream>
    using namespace std;
    unsigned long long n,f[1000001];
    int main()
    {
        freopen("siege.in","r",stdin);
        freopen("siege.out","w",stdout);
        scanf("%lld",&n);
        f[1]=2;
        f[2]=3;
        for (int i=3;i<=n;i++) f[i]=(f[i-1]+f[i-2])%100000007;
        printf("%lld",f[n]);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }

    100%思路:矩阵乘法
    这里写图片描述
    由此可以推出100%解法,n-1次方要用快速幂做

    100%代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    long long n,a[2],b[2][2],c[2][2],d[2][2],e[2];
    void ksm(long long x)
    {
        memcpy(b,c,sizeof(b));
        while (x)
        {
            if (x&1)
            {
                memset(d,0,sizeof(d));
                for (int i=0;i<2;i++)
                    for (int j=0;j<2;j++)
                        for (int k=0;k<2;k++)
                            d[i][j]=(d[i][j]+b[i][k]*c[k][j])% 100000007;
                memcpy(b,d,sizeof(b));
            }
            memset(d,0,sizeof(d));
            for (int i=0;i<2;i++)
                for (int j=0;j<2;j++)
                    for (int k=0;k<2;k++)
                        d[i][j]=(d[i][j]+c[i][k]*c[k][j])% 100000007;
            memcpy(c,d,sizeof(c));
            x=x>>1;
        }
    }
    int main()
    {
        freopen("siege.in","r",stdin);
        freopen("siege.out","w",stdout);
        scanf("%lld",&n);
        a[0]=2; a[1]=3;
        if (n<=2) printf("%lld",a[n-1]);
        else 
        {
            c[0][1]=c[1][0]=c[1][1]=1;
            ksm(n-2);
            for (int i=0;i<2;i++)
                for (int j=0;j<2;j++)
                    e[i]=(e[i]+a[j]*b[j][i]% 100000007)% 100000007;
            printf("%lld",e[0]);
        }
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
  • 相关阅读:
    Java类加载器总结
    Java程序编译和运行的过程
    Spring+Struts2+Hibernate整合
    Spring+MyBatis+SpringMVC整合
    声明式事务管理
    Scala sbt 添加国内镜像
    持续天数算法
    idea run shell set user name
    java insert mysql 中文乱码
    Samba服务器 安装
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8412268.html
Copyright © 2011-2022 走看看