zoukankan      html  css  js  c++  java
  • 2016.7.18 NOIP2014提高组day1解题报告

    乌鸦嘴如我......果然考差了,直接原因是第二题审错题,当然,深层原因绝不会这么简单。不知道自己花在解题报告上的时间是否有意义,毕竟这些时间本可以改好几道题出来,的确要反思一下。

    考试分析:

    1.做题习惯不好,不能只观察数据,要结合题给其他条件,站在逻辑的高度。这次审错题个人觉得很经典:把特殊的树当成了链来做,这显然是没有顾全大局的,说明在思考时未能抹去之前错误的认识,完全没有思考解题方法的正确性,还是太急了,要学会反向思考;

    2.实现代码太慢,完全没有时间思考第三道题,本来按照思路应该很容易发现动规比深搜快很多的,但却担心来不及写放弃了,要多刷题;

    3.花在废话上时间太多,写结题报告显然比调程序简单一点,所以我会花大量的时间来写解题报告,本来总结归纳也是很有用的,但是现在时间不够,找到弱点也没时间落实,不如跟好老师的步伐,尤其是在解题报告里废话少一点;

    题目分析:

    一.生活大爆炸版石头剪刀布

    题意:NCAC题;

    题目分析:技巧关键词:取余,对称,直接加分;

    代码:

        #include<cstdio>

    #include<iostream>

    #include<cmath>

    #include<cstdlib>

    #include<cstring>

    #include<string>

    #include<algorithm>

    #include<queue>

    #include<set>

    using namespace std;

    int n,na,nb,a[205],b[205],stua,stub;

    int ovo[5][5]={{0,0,1,1,0},{1,0,0,1,0},{0,1,0,0,1},{0,0,1,0,1},{1,1,0,0,0}};

    int main()

    {

             freopen("rps.in","r",stdin);

             freopen("rps.out","w",stdout);

             scanf("%d %d %d",&n,&na,&nb);

             for(int i=0;i<=na-1;i++)

             scanf("%d",&a[i]);

             for(int j=0;j<=nb-1;j++)

             scanf("%d",&b[j]);

             for(int i=0;i<=n-1;i++)

             {

                       stua+=ovo[a[i%na]][b[i%nb]];

                       stub+=ovo[b[i%nb]][a[i%na]];

             }

             printf("%d %d",stua,stub);

             return 0;

    }

    二.联合权值

    题意:隔一点的树:n 200 000 w 10 000;

    题目分析:

        根据题意很容易发现任意两点仅一条路径,发现这条性质以后把图画出来会发现,每次求的就是任意两个子节点的乘积,(树)(仅一个前驱)然后好笑的事情发生了:我把图一画——链嘛,然后编了很久,自以为拿了一百,结果......呵呵(手动微笑)所以拿到题目以后先自己画一个图,再分析样例,并且自己的图一定要是最具一般性的!再想计算时的简化(比如直接找儿子),当然大神提供的一个式子为100%提供了可能,不太好打,可以看程序理解。顺便,longlong运算要比int慢很多,写这种多过一组是一组的程序,一定要能简化的地方都简化!;

    (链的愚蠢程序)   

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<set>
    using namespace std;
    const int MAXN=200005,m=10007;
    int sta[MAXN],fin[MAXN],n,w[MAXN],used[MAXN],inf[MAXN][2],flg,maxn,tot,flg2;
    struct pie
    {
        int rig,lef;
    }lace[MAXN];
    void cre(int k,int dot,int las)
    {    
        used[k]=1;
        lace[k].lef=las;
        lace[las].rig=k;
        int k1=inf[dot][0]+inf[dot][1]-k;
        int dot1=fin[k1]+sta[k1]-dot;        
        if(k1==0){flg2=dot;lace[k].rig=-1;return;}
        cre(k1,dot1,k);
    }
    void res(int dot,int k,int las)
    {
        maxn=max(maxn,w[las]*w[dot]);
        tot+=(w[las]%m)*(w[dot]%m)%m;
        tot%=m;
        if(lace[k].rig==-1)return;
        int k1=lace[k].rig;
        int dot1=fin[k1]+sta[k1]-dot;
        int las1=fin[k]+sta[k]-dot; 
        res(dot1,k1,las1);
    }
    void init()
    {
        scanf("%d",&n);
        for(int i=1;i<=n-1;i++)
        {
        scanf("%d %d",&sta[i],&fin[i]);
        if(inf[sta[i]][0])inf[sta[i]][1]=i;
        else inf[sta[i]][0]=i;
        if(inf[fin[i]][0])inf[fin[i]][1]=i;
        else inf[fin[i]][0]=i;
        }
        for(int i=1;i<=n;i++)
        scanf("%d",&w[i]);
        for(int i=1;i<=n;i++)
        if(!inf[i][1])
        {flg=i;break;}
        int k3=inf[flg][0];
        lace[k3].lef=-1;
        used[k3]=1;
        int dot=sta[k3]+fin[k3]-flg;
        int k2=inf[dot][0]+inf[dot][1]-k3;
        int dot1=fin[k2]+sta[k2]-dot;
        if(k2==0){
        flg2=dot;lace[k3].rig=-1;}
        else  cre(k2,dot1,k3);
    }
    int main()
    {
        freopen("link.in","r",stdin);
        freopen("link.out","w",stdout);
        init();
        int k1=inf[flg][0];
        int k2=lace[k1].rig;
        if(k2!=-1)
        {
        int dot=fin[k2]+sta[k2]-fin[k1]-sta[k1]+flg;
        res(dot,k1,flg);
        }
        printf("%d %d",maxn,(tot*2)%m);
        return 0;
    }

    100%的程序

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<set>
    using namespace std;
    const int MAXN=200005,m=10007;
    int maxn,tot,sta,fin,n,w[MAXN],a[MAXN],b[MAXN],c,d,ans;
    struct TREE
    {
        int f,dot,nex;
    }lace[2*MAXN];
    int main()
    {
        freopen("link.in","r",stdin);
        freopen("link.out","w",stdout);
        scanf("%d",&n);
        for(int i=1;i<=n-1;i++)
        {
        scanf("%d %d",&sta,&fin);
        lace[2*i-1].f=sta;lace[2*i-1].dot=fin;lace[2*i-1].nex=a[sta];a[sta]=2*i-1;
        lace[2*i].f=fin;lace[2*i].dot=sta;lace[2*i].nex=a[fin];a[fin]=2*i;
        }
        for(int i=1;i<=n;i++)
        {scanf("%d",&w[i]);}
        for(int i=1;i<=n;i++)
        {int j=a[i];tot=0;c=0;d=0;
        while(lace[j].nex)
        {
            tot++;b[tot]=w[lace[j].dot];
            c+=((b[tot]%m)*(b[tot]%m))%m;d+=b[tot]%m;
            c%=m;d%=m;
            j=lace[j].nex;
        }
        tot++;b[tot]=w[lace[j].dot];
        c+=((b[tot]%m)*(b[tot]%m))%m;d+=b[tot]%m;
        c%=m;d%=m;d*=d;d%=m;
        sort(b+1,b+tot+1);
        ans+=(d-c+m)%m;ans%=m;
        maxn=max(maxn,b[tot]*b[tot-1]);
        }
        printf("%d %d",maxn,ans);
        return 0;
    }
    (这里是不需要除以二的,模后除和除后模因为是int都会出问题,所以只能:1.用逆元;2.观察;)

    三.飞扬的小鸟

    题意:越过障碍,模拟+动规;(要把每个情况对应时间还是时刻弄清楚)

    题目分析:发现x,y可以表示状态后我就打算动规,但想一想x*y时间复杂度好高啊(愚蠢),而且时间又不够就放弃了呵呵(手动微笑),所以实现代码一定要快,为最后一道题留够充足时间,你不会只想要200吧;

        这里加了一个优化,直接动规只能70%,但因为你可以从自己推上来,所以你重复计算了很多值,这种重复剪的思维很重要(大神是从背包想出来的,666)

  • 相关阅读:
    学习Python之路
    基本数据类型
    pthon之变量
    函数、参数、局部函数and函数内变量修改、嵌套函数
    文件操作M2
    文件IO操作二
    文件I/O操作
    字符编码
    数据类型之集合,数据类型总结
    数据类型之列表和元组
  • 原文地址:https://www.cnblogs.com/SindarDawn/p/5683663.html
Copyright © 2011-2022 走看看