zoukankan      html  css  js  c++  java
  • 2019中山纪念中学夏令营-Day1[JZOJ]

    T1 题目描述:

    题目描述

             Wexley最近发现了一个古老的屏幕游戏。游戏的屏幕被划分成n列。在屏幕的底端,有一个宽为m列的篮子(m<n)。在游戏过程中,Wexley能左右移动这个篮子,            Wexley的操作很犀利,移动是瞬间完成的,但是篮子必须始终都在屏幕中。 苹果从屏幕的顶端落下,每个苹果从n列中的某一列顶端掉落,垂直掉落到屏幕的底端。每个苹果总是在上一个苹果掉落到底端的时候开始掉落。Wexley想要通过移动篮子来接住所有的苹果。起先,篮子在屏幕的最左端。
             求出Wexley要接住所有的苹果所需移动的最短距离。 
     

    输入

    第一行,两个整数n、m,如题所述
    第二行,一个整数k,表示掉落的苹果总数
    接下来k行,每行一个整数Ai,表示每个苹果掉落的位置

    输出

    一行一个整数,表示所需移动最短距离
     

    样例输入

    Sample Input1:
    5 1
    3
    1
    5
    3

    Sample Input2:
    5 2
    3
    1
    5
    3

     

    样例输出

    Sample Output1:
    6

    Sample Output2:
    4

     
     

    数据范围限制

    【数据范围】
    对于30%的数据,m<n<=5,k<=10
    对于100%的数据,1<=m<n<=10,1<=k<=20

    思路:贪心模拟,使每次移动数尽量少即可.难度较容易。

    附上AC代码:(考试完了重新码的,考试的时候的代码有点小问题)

    #include <cstdio>
    #include <iostream>
    using namespace std;
    int n,m,k,a[21];
    int b[21],head,ans,tmp;
    int main()
    {
        freopen("apple.in","r",stdin);
        freopen("apple.out","w",stdout);
        scanf("%d %d",&n,&m);
        scanf("%d",&k);
        b[0]=1;
        for(int i=1;i<=k;i++)
        {
            scanf("%d",&a[i]);
        }
        head=m;
        for(int i=1;i<=k;i++)
        {
            if(head>=a[i] && (head-m+1)<=a[i])
            continue;
            if(head<a[i])
            {
                ans+=a[i]-head;
                head+=a[i]-head;
                continue;
            }
            if((head-m+1)>a[i])
            {
                int tmp=head;
                head=a[i]+m-1;
                ans+=tmp-head;
                continue;
            }
        }
        printf("%d",ans);
    }

    T2 

    题目描述

             Leo是一个快乐的火星人,总是能和地球上的OIers玩得很high。
             2012到了,Leo又被召回火星了,在火星上没人陪他玩了,但是他有好多好多积木,于是他开始搭积木玩。
           火星人能制造n种积木,积木能无限供应。每种积木都是长方体,第i种积木的长、宽、高分别为li、wi、hi。积木可以旋转,使得长宽高任意变换。Leo想要用这些积木搭一个最高的塔。问题是,如果要把一个积木放在另一个积木上面,必须保证上面积木的长和宽都严格小于下面积木的长和宽。这意味着,即使两块长宽相同的积木也不能堆起来。
           火星上没有电脑,好心的你决定帮助Leo求出最高的塔的高度。

    【提示】
    每种积木都可以拆分成高度分别为li、wi、hi的三种积木,另两边作为长和宽,保证长>=宽。
     

    输入

    第一行,一个整数n,表示积木的种数
    接下来n行,每行3个整数li,wi,hi,表示积木的长宽高

    输出

    一行一个整数,表示塔高的最大值
     

    样例输入

    Sample Input1:
    1
    10 20 30


    Sample Input2:
    2
    6 8 10
    5 5 5



    Sample Input3:
    5
    31 41 59
    26 53 58
    97 93 23
    84 62 64
    33 83 27

     

    样例输出

    Sample Output1:
    40


    Sample Output2:
    21


    Sample Output3:
    342
     

    数据范围限制

    对于30%的数据 n<=8
    对于100%的数据 n<=3000,最后答案不会超过32位整型

    思路:标答:动态规划。

      骗分:暴力DFS.

    附上DFS30分代码TLE

    #include <cstdio>
    #include <iostream>
    using namespace std;
    int n,a[3002][3],ans=0,mina;
    const int inf=999999999;
    void swap(int a,int b)
    {
        int c=b;
        b=a;
        a=c;
    }
    void dfs(int l,int w,int high)
    {
        if(high>ans)
        ans=high;
        if(w==mina)
        {
            return;
        }
        for(int i=1;i<=n;i++)
        {
            if(a[i][0]<l && a[i][1]<w)
            dfs(a[i][0],a[i][1],high+a[i][2]);
            if(a[i][0]<w && a[i][1]<l)
            dfs(a[i][1],a[i][0],high+a[i][2]);
            if(a[i][0]<l && a[i][2]<w)
            dfs(a[i][0],a[i][2],high+a[i][1]);
            if(a[i][0]<w && a[i][2]<l)
            dfs(a[i][2],a[i][0],high+a[i][1]);
            if(a[i][1]<l && a[i][2]<w)
            dfs(a[i][1],a[i][2],high+a[i][0]);
            if(a[i][1]<w && a[i][2]<l)
            dfs(a[i][2],a[i][1],high+a[i][0]);
            if(a[i][1]>l && a[i][2]>w)
            continue;
        }
    }
    int main(){
        freopen("brick.in","r",stdin);
        freopen("brick.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            int a1,b1,c1;
            scanf("%d %d %d",&a1,&b1,&c1);
            if(c1>b1)
            swap(c1,b1);
            if(a1<b1)
            swap(a1,b1);
            if(c1>b1)
            swap(c1,b1);
            if(mina>c1)
            mina=c1;
            a[i][0]=a1;a[i][1]=b1;a[i][2]=c1;
        }
        dfs(inf,inf,0);
        printf("%d",ans);
    }

    100分代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    struct Node{
        int w,l,h;
    }a[10001];
    int Max(int a,int b)
    {
        if(a>b)
        return a;
        return b;
    }
    int Min(int a,int b)
    {
        if(a>b)
        return b;
        return a;
    }
    bool bdx(Node c,Node d)
    {
        return c.l<d.l;
    }
    int main()
    {
        freopen("brick.in","r",stdin);
        freopen("brick.out","w",stdout);
        int n,f[10001],ans;
        scanf("%d",&n);
        int o,p,q;
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d %d",&o,&p,&q);
            a[i].l=Max(o,p);a[i].w=Min(o,p);a[i].h=q;
            a[i+n].l=Max(o,q);a[i+n].w=Min(o,q);a[i+n].h=p;
            a[i+2*n].l=Max(p,q);a[i+2*n].w=Min(p,q);a[i+2*n].h=o;
        }
        std::sort(a+1,a+3*n+1,bdx);
        for(int i=1;i<=3*n;i++)
            f[i]=a[i].h;
        for(register int i=3*n;i>=1;i--)
            for(register int j=i+1;j<=3*n;j++)
                if(a[i].w<a[j].w && a[i].l != a[j].l)
                    f[i]=Max(f[j]+a[i].h,f[i]);
        for(int i=1;i<=3*n;i++)
        ans=Max(ans,f[i]);
        printf("%d",ans);
    }

    T4

    题目描述

               马上假期就要到了,THU的神犇Leopard假期里都不忘学霸,现在有好多门功课,每门功课都耗费他1单位时间来学习。
               他的假期从0时刻开始,有1000000000个单位时间(囧rz)。在任意时刻,他都可以任意一门功课(编号1~n)来学习。
               因为他在每个单位时间只能学习一门功课,而每门功课又都有一个截止日期,所以他很难完成所有n门功课。
               对于第i门功课,有一个截止时间Di,若他能学完这门功课,他能够获得知识Pi。
               在给定的功课和截止时间下,Leopard能够获得的知识最多为多少呢?
     

    输入

    第一行,一个整数n,表示功课的数目
    接下来n行,每行两个整数,Di和Pi

    输出

    输出一行一个整数,表示最多学得的知识数
     

    样例输入

    3
    2 10
    1 5
    1 7


     

    样例输出

    17

    【样例说明】
    第一个单位时间学习第3个功课(1,7),然后在第二个单位时间学习第1个功课(2,10)
     

    数据范围限制

    10% n<=25
    60% n<10000
    100% 1<=n<=100000,Di、Pi<=1000000000
    最后的答案可能超过32位整型
     

    思路:标答:最小堆

      接近标答:贪心。

    附上80分贪心代码(TLE+RE)

    #include <cstdio>
    #include <algorithm>
    #define rr register
    bool time[100001],bj;
    struct Node{
        int di,pi;
    }a[100001];
    inline bool bdx(Node c,Node d)
    {
        return c.pi>d.pi;
    }
    int main()
    {
        freopen("study.in","r",stdin);
        freopen("study.out","w",stdout);
        rr long long ans=0LL;
        rr int n,mark=0;
        scanf("%d",&n);
        for(rr int i=1;i<=n;i++)
        scanf("%d %d",&a[i].di,&a[i].pi);
        std::sort(a+1,a+n+1,bdx);
        for(rr int i=1;i<=n;i++)
        {
            if(!time[a[i].di])
            {
                time[a[i].di]=true;
                ans+=a[i].pi;
            }
            else
            {
                rr int j=a[i].di;
                while(time[j])
                j--;
                if(j<1)
                continue;
                ans+=a[i].pi;
                time[j]=true;
            }
        }
        printf("%lld",ans);
    }

    目前这道题还没AC...

  • 相关阅读:
    Codeforces Round #104 (Div. 1) C. Lucky Subsequence
    UVALive 4848 Tour Belt
    ...
    HDU4609 计数问题+FFT
    hdu6129 Just Do It!
    hdu6133 Army Formations 线段树合并
    迭代FFT
    第二类Stirling数
    project euler113
    HBase 常用shell命令
  • 原文地址:https://www.cnblogs.com/XYYXP/p/2019-8-1_ZSJNZX_OJ_TEAM-C_PUJI_DAY1.html
Copyright © 2011-2022 走看看