2016.12.03【初中部 NOIP提高C组】模拟赛题解

来源:互联网 发布:淘宝网禁止出售的药方 编辑:程序博客网 时间:2024/06/05 02:20

T1:

题目大意,N个人构成一个环,第一次给1,2号人糖,以后,从第二个人,跳过1次,2次,3次。。。(按照时间推移)给下一个人。给出一个N,问这N个人如此做是否能够都获得糖果。

           暴力,可以发现答案是2^n的话就符合条件。

T2:

题目大意:有n个对于两两之间对抗,求k的对抗总和最少。(k<n)

           因为k<n,所以 我们不需要n²去两两枚举。排序后,对于一个数,只有和他前面和后面的差的绝对值是最小值,跟后面的,是下一个要判断的,所以只需要排序一下跟当前数跟前面数的差,求和即可。

T3:

          题目大意:给一个正整数X,一个长度为mX-因子链是指这样一个序列:X0=1X1X2,。。,Xm=X满足:Xi<Xi+1同时Xi|Xi+1(Xi+1能被Xi整除)要求X-因子链的最大长度Len和长度为LenX-因子链的数量。

           30分:

           统计出因子,然后直接深搜即可。显然超时。

           100分:

           暴力显然是不可以的。因为重点条件是len,所以我们先考虑len。要使len最小,a[i]*k=a[i+1],k相对来说,一定要小,才尽可能多。开头固定了是1,所以我们只需要对x分解质因数即可,统计出质因数个数即为len。

           对于第二问,不考虑重复的情况,排列组合就是len!,但是有重复的情况,根据排列组合CP(couple?),重复元素的个数的阶乘即为重复次数,除一下即可。

T4: 

题目大意:给你前序遍历和后序遍历,求中序遍历的情况总数。

           对于这列遍历问题,对于我这个不会打递归的人来说,好难额。。

           前序遍历:根左右     后序遍历:左右根

           我们把后序遍历的字符串倒过来,变成了根右左。

           把后序遍历的翻转,得到顺序为“根右左”。可以看出,两个序列的第一个(根)是相同的。序列一的第二个字母是左子树的根,序列二的第二个字母是右子树的根。如果左右子树的根不同,就分开两个子树,分别求方案数,乘起来;如果左右子树的根相同,就把这个子树的方案数乘2。

           用数据说话:

               QWERTYUIOP
               倒转后:QWYUIOPERT

Q为全树的跟,W为左子树或者右子树的根。两种情况,方案*2;不考虑这两个东西了。

剩下:ERTYUIOP和YUIOPERT,一个是左右,一个是右左。循环过去,发现左边是ERT,右边是YUIOP。我们于是把他分成两段。发现一样,我们就*4个2,2个2,答案128.最多只分一次,所以水法即可。但是递归逻辑强,讲一下:

procedure dg(x,y:longint);//表示x~y一段var        i,j,max,p:longint;begin        s1:='';        max:=0;        for i:=x to y do        begin                s1:=s1+s[i];                if pos(s1,ss)>0 then                        inc(max);        end;//寻到左子树最大长度        if max=y-x+1 then//如果等于全部的话,也就是分解了                ans:=ans*(1 shl (y-x))//累加当前方案        else        begin                dg(x,x+max-1);//左根                dg(x+max,y);//右根        end;end;

0 0
原创粉丝点击