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

来源:互联网 发布:证件照蓝底渐变软件 编辑:程序博客网 时间:2024/06/03 19:51

题目:https://jzoj.net/senior/#contest/problems/1753

T1:

第一题就是一个数学题目而已,只要懂得∑这个符号的意思,以及有良好的思维即可AC。贴一下最难的一段的就是Yij的:

for i:=1 to n do        begin                for j:=1 to 8 do                begin                        ans:=0;                        for k:=1 to n do                                ans:=ans+abs(sum[k,j]-avg[j]);                        if ans=0 then                                y[i,j]:=0                        else                                y[i,j]:=(sum[i,j]-avg[j])/(ans/n);                end;        end;
T2:

第二题很明显是二分,二分答案。刚开始看题以为是DP,可以看看n的范围还是算了。二分最短的时间,假设最短时间为x,然后对于每个衣服a[i]-烘干值*x,最后看看x的时间够不够用(自己思考,差不多就是每个div一下的意思),够则缩,反之则扩。注意r的范围尽量弄大一点也没关系,不然可能爆0。

while l<r do        begin                mid:=(l+r) div 2;                if pd(mid) then                begin                        r:=mid;                        if mid<min then min:=mid;                end                else                l:=mid+1;        end;
T3:

第三题考试的时候想到了暴力和二分,可惜二分不会实现。讲完题后我同桌proking也实现了许久。讲题时,一位神犇告诉了我们一个非常厉害的算法。

例如数据是:1,2,3,4,5,我们就把他复制一次,就是1,2,3,4,5,1,2,3,4,5。很明显,最大和为1-5这个序列的和15,注意是原序列。然后我们设一个队列,一旦队列的总和大于15的一半,就开始删掉队头的元素。最后的结果就是每次删完后队列最大的总和。

for i:=1 to 2*n do        begin                inc(len);                s:=s+a[i];                while s>ans div 2 do                begin                        dec(len);                        dec(s,a[l]);                        inc(l);                end;                if s>max then max:=s;                if s=ans div 2 then break;        end;
T4:

注意,题目的意思是,选取开头和结尾,期间的数,要大于开头,小于结尾,可以无顺序。据说这道题班上没人想出正解。但是有人想出了O(n^n)水过,数据小没办法。不过还是加了许多优化的。枚举起点,设一个max,表示当前队列中最大(终点)值为多少,往下搜,如果此点>max,则设此点为终点,这样保证了队列终点最大。

for i:=n downto 2 do        begin                min:=a[i];                for j:=i downto 1 do                begin                        if a[j]>a[i] then break;                        if (a[j]<min)or((j=i)and(a[j]<min)) then                        begin                                ans:=j;                                min:=a[j];                        end;                end;                if (i-ans+1>max)and(ans<>0) then max:=i-ans+1;        end;
总结:

这次考得很差,该做的题目没做对,主要是数学能力和题目理解能力不太强,今后急需改正

0 0
原创粉丝点击