2016.08.18【初中部 NOIP普及组 】模拟赛

来源:互联网 发布:天子网络 编辑:程序博客网 时间:2024/05/18 05:37

总结:

      一直刷提高组的我,今天刷了普及组。翻车了。老师找了我谈人生。以往是被难题水,现在是被水题水了。妈的智障,特别是做第二题做了3个小时,剩下45分钟,连调试都不够。下一次一定要合理安排时间,如果大于20分钟思考一定要切题,不可因为一道题目而耽误了其他题

估分:0+0+0+0(个人爱好)

得分:100+10+0+0

算了,往事不堪回首,转入正题。

T1:

       第一道题想了很久很久,都不知道怎么策略是什么。刚开始我设f[i]表示到i这个位置的最少步数。于是,第二个j循环就懵逼了。1 to a[i]?也不对,不一定是a[i],可能是a[i-1].....只要能写的都写了。

          幸亏最后想到了1 to i,看看当前的位置是从哪个地方推过来的,如果i-j的位置他的步数可以到达该地就DP。

<span style="font-size:18px;"><strong>for i:=2 to n do                for j:=1 to i do                        if a[i-j]>=j then f[i]:=f[i-j]+1;</strong></span>
f[n]就是答案。

T2:

        第二题看到题目,我很庆幸自己玩过风靡全球的2048游戏,因为很多同学都不知道是什么东东。然后,玩过了才是真正的悲惨。感觉被题目水了。2048可以连续撞,他不可以,而且第i,j的位置撞了,以后这个位置不能撞。大家别掉坑里了。

        我的方法很简单,就是暴力模拟。我贴其中一个位置的代码然后讲解。

                     'R':begin                                for i:=1 to 4 do                                        for j:=4 downto 1 do//枚举,这样枚举可以避免连环撞,从右边到左边                                        if a[i,j]>0 then//如果不为0才有价值                                        begin                                                k:=j+1;                                                if k>4 then continue;                                                while (a[i,k]=0)and(k<4) do                                                        inc(k);//找到一个非0的位置                                                if ((a[i,k]=a[i,j])and(k<>j))and(bz[i,k]) then                                                begin                                                        a[i,k]:=a[i,k]*2;                                                        a[i,j]:=0;                                                        bz[i,k]:=false;                                                end//如果当前位置可以撞就撞                                                else                                                if a[i,k]=0 then                                                begin                                                        a[i,k]:=a[i,j];                                                        a[i,j]:=0;                                                end//如果为0,就像是最左侧,或者最右侧,赋值                                                else                                                if a[i,k]>0 then                                                begin                                                        if k-1<>j then                                                        begin                                                                a[i,k-1]:=a[i,j];                                                                a[i,j]:=0;                                                        end;                                                end;//如果当前这个位置不为0,但是他不可以撞,那么就把他前一个位置赋值                                        end;                            end;
细心,每个方法都是对的,只是细节地方。大家要好好玩玩2048

T3:

第三题考试的时候所有时间都放在了第二题,调试了半天才10分,所以没把暴力打出来。

            30%:暴力递归3种方案。

            100%:

                      1、二分+模拟判断:

                            二分最终的答案ans
每个礼包至少耗掉一个键盘、一个鼠标,
所以问题变成了:
豪华礼包x个:1键盘
幸运礼包y个:1U盘
普通礼包z个:1鼠标
由于相邻两位领礼包的顾客拿到的礼包类型都是不同的,所以:
x <= y+z+1
y <= x+z+1
z <= x+y+1
判断即可。(没打代码,也没理解,于是使用第二种神奇的方法)
                      2、数学知识:

                                 

<span style="font-size:18px;">if x>y then//其中一个三元组的判断                begin                        p:=min(x div 3,min(y div 2,min(x-y,z)));//取最小值                        x:=x-3*p;//减去对应的系数                        y:=y-2*p;                        z:=z-p;                        ans:=ans+p*2;//累加组合个数                end</span>
T4:
          极其简单???认识链接表的就简单吧。不然爆空间

<span style="font-size:18px;">procedure insert(x,y,z:longint);begin        inc(tot);//当前是第tot个表        tov[tot]:=y;//存他对应到达的点        len[tot]:=z;//其路径        next[tot]:=last[x];//存他的tot位置的x他上一个数第几个,好像就是父亲节点那样子        last[x]:=tot;//表示以x为起点他的各个位置end;</span>
大概这样,然后水一次SPFA就好,优化时间就卡一下常数

while head<tail do        begin                head:=head mod 582156+1;//循环队列优化时空效率                x:=d[head];                y:=la[x];//取最后出现过的位置                while y<>0 do                begin                        if dis[l[y]]>dis[x]+c[y] then                        begin                                dis[l[y]]:=dis[x]+c[y];                                tail:=tail mod 582156+1;                                d[tail]:=l[y];                        end;                        y:=pre[y];//取他的父亲,就是取他上一个                end;        end;

3 0