zoukankan      html  css  js  c++  java
  • 五校联考解题报告

    Day 1(题目在这儿)

    T1 骰子

    题意:

    有一个 的网络的左上角(1,1)有一个

    有一个骰子上面为  1 ,下面为6 左面为 4,右面为 3,前面为 2,后面为 5),先从左滚

    右然后滚下去滚到最左边…..,每次记最上边点数为每次得分,问滚完以后可以得多少分?

    解:

    开始定义shang=1,xia=6,zuo=4…

    暴力:

    对于 数据, 模拟在每个格子上的状态,数据可以到10000左右不会超时。

    而每次滚动需要考虑三种操作。

    ①     向左滚

    右变上,上变左,左变下,下变右。

    LL solz()
    {
        LL temp=shang;
        shang=you;you=xia;xia=zuo;zuo=temp;
        return shang;
    }

    ②     向右滚

    LL soly()
    {
        LL temp=shang;
        shang=zuo;zuo=xia;xia=you;you=temp;
        return shang;
    }

    ③     向下滚

    LL sold()
    {
        LL temp=shang;
        shang=hou;hou=xia;xia=qian;qian=temp;
        return shang;
    }

    对于100%的数据,需要观察一下筛子滚动的价值规律。

    骰子对面相加价值为7,滚动一周价值为14,我们可以直接考虑滚动一行可以滚动多少周那么可以直接 14,然后一行剩余的最多枚举3次,时间复杂度优秀。

    /***************************
    一轮noip模拟考试 Day1 T1
    --2018.8.26
    ***************************/
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    #define LL long long
    LL shang=1,xia=6,zuo=4,you=3,qian=2,hou=5;
    LL n,m,sum,ans;
    LL solz()
    {
        LL temp=shang;
        shang=you;you=xia;xia=zuo;zuo=temp;
        return shang;
    }
    LL soly()
    {
        LL temp=shang;
        shang=zuo;zuo=xia;xia=you;you=temp;
        return shang;
    }
    LL sold()
    {
        LL temp=shang;
        shang=hou;hou=xia;xia=qian;qian=temp;
        return shang;
    }
    int main()
    {
    //    freopen("dice.in","r",stdin);
    //    freopen("dice.out","w",stdout);
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++)
        {
            ans+=(m/4)*14;
            if(i%2==1&&m%4!=0)
            {
                ans+=shang;
                for(int j=1;j<m%4;j++)ans+=soly();            
            }
            else if(m%4!=0)
            {
                ans+=shang;
                for(int j=1;j<m%4;j++)ans+=solz();
            }
            sold();
        }
        printf("%lld",ans);
    //    fclose(stdin);fclose(stdout);
    }

    T2 子序列

    题意:

    给定一个序列 .

    求序列中有多少对三元组(I,j,k),满足 或者$a[i] le a[j] le a[k]$或者$a[k] le a[j] le a[i]$ 。

    解:

    对于20%枚举i,j,k即可。

    对于50%, 处理某个数左边有多少大于它的数,有多少小于它的数,右边有多少…,然后枚举j点,所以每个点满足的三元组数量为

           左边大于$a[j]$的个数$ imes$右边小的个数+左边小的个数$ imes$右边大的个数

    /*****************
    考场50分代码
    ********************/
    int main()
    {
        freopen("sub.in","r",stdin);
        freopen("sub.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)a[i]=read();
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                if(a[j]>a[i])big[i]++;
                if(a[j]<a[i])small[i]++;
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=i+1;j<=n;j++)
            {
                if(a[j]!=a[i])
                {
                    if(a[j]>a[i]&&big[j])ans+=big[j];
                    if(a[j]<a[i]&&small[j])ans+=small[j];
                    ans%=mod;
                }
            }
        }
        printf("%d",ans);
        fclose(stdin);fclose(stdout);
    }

    对于100%的数据,则需要先离散化,用到了两个树状数组。

    将复制离散化完的的数组排序,二分查找下标加到第一个树状数组里,区间[1,i]的和表示的为小于以i为下标的离散化数组中的数的个数,那么当枚举到i时,树状数组中区间[1,a[i]-1](a[i]表示在离散化序列中a[i]的位置)的和表示a[1--i]中小于a[i]的数字个数,总数为i-1个,那么小于等于a[i]的数字个数为树状数组中区间[1,a[i]]的和,那么大于a[i]的数的个数为i-1-query(1,a[i-1])。

    这部分代码:

        for(int i=1;i<=n;i++)
        {
            a[i]=lower_bound(tmp+1,tmp+1+n,a[i])-tmp;
            l[i]=query(small,a[i]-1);    //比i小(左边)
            ll[i]=i-1-query(small,a[i]);
            add(small,a[i],1);
        }

    同理处理右边的数,为了简便可以倒序枚举序列。

    /************************
    一轮Noip模拟赛Day 1 T2
    --8.26
    树状数组模板见于最后
    *************************/
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    #define LL long long
    #define mod int(1e9+7)
    LL n,a[200010],big[200020],small[200010],ans;
    LL tmp[200020];
    LL l[200020],r[200020],ll[200020],rr[200020];
    int lowbit(int i){ return i & -i; }
    LL query(LL *c,LL i)
    {
        LL sum=0;
        while(i>0)
        {
            sum+=c[i];
            i-=lowbit(i);
        }
        return sum;
    }
    LL add(LL *c,int i,LL val)
    {
        while(i<=n)
        {
            c[i]+=val;
            i+=lowbit(i);
        }
    }
    int main()
    {
    //    freopen("sub.in","r",stdin);
    //    freopen("sub.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            tmp[i]=a[i];
        }
        sort(tmp+1,tmp+1+n);
        for(int i=1;i<=n;i++)
        {
            a[i]=lower_bound(tmp+1,tmp+1+n,a[i])-tmp;
            l[i]=query(small,a[i]-1);    //比i小(左边)
            ll[i]=i-1-query(small,a[i]);
            add(small,a[i],1);
        } 
        for(int i=n;i>=1;i--)
        {
            r[i]=query(big,a[i]-1);        //右边比i小的。 
            rr[i]=n-i-query(big,a[i]);
            add(big,a[i],1);
        }
        for(int i=1;i<=n;i++)
        {
            ans+=(l[i]*rr[i])%mod;
            ans+=(ll[i]*r[i])%mod;
            ans%=mod;
        } 
        printf("%lld
    ",ans);
    //    fclose(stdin);fclose(stdout);
    }

    T3 平面图

    尚不会做正解,暂时只会10分。

    子任务1:暴力搜索。

    子任务3:n为奇数答案为0,偶数答案为2(开long long)

    65递推式:$$ans = ((pow((pow(n, 2) % HA - (3 * n - 3) % HA) % HA, m % HA) % HA + ((n - 1) % HA) * ( (pow(3 - n, m) % HA) + (pow((1 - n) % HA, m) % HA) ) % HA) % HA)  + (pow(n, 2) % HA) - (3 * n - 1) % HA;$$

    HA为%数。

    Day 2 (here)

    T1

    题意:

    给你n个区间,每次区间[l,r]内的数+1,求最大的点数是多少?

    解:

    对于30%数据,O(n)枚举区间每一个数每次+1,总复杂度O( )

    对于另外20%, 离散化一下,枚举+1.

    另外20% 据说是考虑不会离散化的学生。

    对于100%,标程居然比暴力都好写。

    离散化一下,每个区间的左端点处+1,r+1处-1,然后统计下前缀和,记录最大的答案。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    #define LL long long
    LL l[200010],r[200020],tmp[400010];
    LL n,ans,MAX,k,sum[433330];
    
    int main()
    {
        freopen("meizi.in","r",stdin);
        freopen("meizi.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld",&l[i],&r[i]);
            tmp[i*2-1]=l[i],tmp[i*2]=r[i];
        }
        sort(tmp+1,tmp+1+2*n);
        for(int i=1;i<=n;i++)
        {
            l[i]=lower_bound(tmp+1,tmp+1+2*n,l[i])-tmp;
            r[i]=lower_bound(tmp+1,tmp+1+2*n,r[i])-tmp;
            sum[l[i]]++;sum[r[i]+1]--;
        }
        for(int i=1;i<=2*n;i++)
        {
            sum[i]=sum[i-1]+sum[i];
            ans=max(ans,sum[i]);
        }
        printf("%lld",ans);
        fclose(stdin);fclose(stdout);
    }

    T2

     [无显示]你网页炸了!

    T3

    数学期望。

    利用数学期望的线性性:期望的和等于和的期望。

  • 相关阅读:
    动画,缩放
    本地公司
    调研 公司信息
    外贸 内贸 经商
    情感 爱情 恋爱
    H5源码
    世界 生活
    标识
    Jackson
    java数据结构
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9540211.html
Copyright © 2011-2022 走看看