2016.07.13【初中部 NOIP提高组 】模拟赛C题解
来源:互联网 发布:qq.com 域名 编辑:程序博客网 时间:2024/05/22 10:35
题目网址:http://blog.csdn.net/fengyingjie2/article/details/51900664
总结:这次比赛考的时候觉得很难很难,改的时候觉得很水很水。觉得考试的时候很多大胆的想法都没有实现,例如第三题,随随便便打了个递归就了事了。总体来说题目不是很难,水平有待提高,敲键盘也要敲多点了/(ㄒoㄒ)/~~我还懂一个道理:暴力出奇迹,水法真神奇!
T1:
第一题我刚看题目,怎么这么水!可是这是提高组的题目。我又看了一遍,n≤10,才发现TG原来有水题,刚开始以为要DP呢~回溯AC!!!O(∩_∩)O~~上代码:
<span style="font-size:14px;">var n,min:int64; i:longint; a,b:array[0..10] of longint;procedure dg(k,ans,numa,numb:int64);//参数代表:枚举到第几个,一共用了多少原料,酸度,和苦度begin if (abs(numa-numb)<min)and(ans>=1) then min:=abs(numa-numb); if k>n then exit; dg(k+1,ans+1,numa*a[k],numb+b[k]);//选 dg(k+1,ans,numa,numb);//不选end;begin readln(n); min:=maxlongint; for i:=1 to n do readln(a[i],b[i]); dg(1,0,1,0); writeln(min);end.</span>T2:
这道题比赛的时候看起来是DP,然而怎么也推不出方程。于是用贪心打了一遍,居然0分!!!如果做过usaco里面A GAME这道题的人99.99%会做这道题。
详解:省略……做出来补充
代码:没做出来……
T3:
第三题刚看题目,其实很熟悉,小学OJ有个同样的题目叫:数列,也是删数的。比赛的时候,其实我想的方法就是正解:把一个数列有的,然而别的数列没有的,这一列,删掉!而且还要重头开始循环删(因为你删掉了某一列之后,可能这3列共同有的这个数你删掉了,导致这一列缺这个数,引起错误),所以,你要删N多次,直到上一次没有删为止。我考试打了个递归,不会实现之前我想的算法,于是10分。。代码:
<span style="font-size:14px;">var i,j,k,n,m,x,y,p,q,ans:longint; a,b,c:array[1..100000]of longint; bz3:boolean; bz,bz1,bz2:array[1..100000]of longint;begin readln(n); for i:=1 to n do begin read(a[i]); bz[a[i]]:=1; end; for i:=1 to n do begin read(b[i]); inc(bz1[b[i]]); end; for i:=1 to n do begin read(c[i]); inc(bz2[c[i]]); end; bz3:=true; while bz3 do//上一次没删过就退出 begin bz3:=false; for i:=1 to n do begin if (bz[a[i]]>0) and ((bz1[a[i]]=0)or (bz2[a[i]]=0)) then//第一列有的别的没有的情况下 begin dec(bz[a[i]]); dec(bz1[b[i]]); dec(bz2[c[i]]);//删掉这一列的数 bz3:=true;//表示删过了, inc(ans); end; end; end; write(ans);end.//这个是同学的代码@hgr,我的代码打得有点猥琐,不好说</span>T4:
考试的时候没看懂。想不到这道题如此简单。意思就是:一个最大的区间包住一个次大的,次大的包住次次大的……求最多能包住多少个区间。
很明显的知道,先排个序,把a[i,1]当做排序的第一元素(第一关键字),然后a[i,2]就是第二个。如果在a[i,1]相等的前提下,a[i,2]较大的优先。a[i,1]从小到大排序。然后我们就做一个最长不上升子序列,来把区间给串起来(包住)。题目N≤100000,所以,n²一定会超时。我们就可以优化一下最长不上升子序列,怎么优化,敬请收看下一段。
最长不上升子序列,就是多了一个F数组,这个F[i]表示第i长度结尾的最小值!把过程说出来可能也听不懂(语文差),还是出个数据来说说吧!
数列:
1 7
1 6
1 5
1 4
2 5
2 5
2 5
排序完变成:
1 7
1 6
1 5
1 4
2 5
2 5
2 5
然后,第一列没用了。第二列为7.6,5,4,5,5,5。一开始,固定把第一个,就是7丢进f数组里面去。f[1]:=7;然后从f数组的每个数倒过来跟后一个比较。6≤7,就把6丢进去,f[2]:=6,5≤f[2],丢进去,f[3]:=5,4≤f[3],f[4]:=4。这时候,问题来了,也是我一开始错的地方。5比f[4]大,我们就不做判断,来到和f[3]比较,发现符合条件5<=f[3],所以我们把f[3+1]的4替换成5.注意:如果F数组最后一个元素不符合当前枚举的a[i,2]数组的条件,就是a[i,2]>f[len],那么我们就要继续从f[len-1~~1]这么范围去枚举,找到了符合条件的,就把符合条件的后一个数,就是f[符合条件为止+1]变成a[i,2]。如果这个数比整个数列都大,就把他跟第一个换。以此类推,f数组为[7,6,5,5,5,5],长度为6,最长不上升子序列就是6了!!效率为O(n logn),够快吧!于是AC,代码:
var n,i,j,sum,min:longint; a:array[0..100000,0..2] of longint; f:array[0..100000] of longint; bz:boolean;procedure q(l,r:longint);var i,j,m1,m2,x:longint;begin i:=l; j:=r; m1:=a[(l+r) shr 1,1]; m2:=a[(l+r) shr 1,2]; repeat while (a[i,1]<m1)or((a[i,1]=m1)and(a[i,2]>m2)) do inc(i); while (a[j,1]>m1)or((a[j,1]=m1)and(a[j,2]<m2)) do dec(j); if i<=j then begin x:=a[i,1]; a[i,1]:=a[j,1]; a[j,1]:=x; x:=a[i,2]; a[i,2]:=a[j,2]; a[j,2]:=x; inc(i); dec(j); end; until i>j; if l<j then q(l,j); if i<r then q(i,r);end;//快排begin readln(n); for i:=1 to n do readln(a[i,1],a[i,2]); q(1,n); f[1]:=a[1,2];//一开始f第一个为a[1,2] sum:=1; for i:=2 to n do begin bz:=false; for j:=sum downto 1 do if f[j]>=a[i,2] then//符合条件了 if sum<>j then//但是并不是f[len]能符合条件的 begin f[j+1]:=a[i,2];//换掉后一个 bz:=true; break;//直接break,加快速度 end else begin inc(sum);//长度+1 f[sum]:=a[i,2];//如果最后一个就符合条件的,就长度+1,把新的a[i,2]丢进去 bz:=true; break; end; if not bz then//如果整个F数组都没a[i,2]大 f[1]:=a[i,2];第一个就换成a[i,2] end; writeln(sum);end.
- 2016.07.13【初中部 NOIP提高组 】模拟赛C题解
- 2016.07.14【初中部 NOIP提高组 】模拟赛C题解
- 2016.07.16【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.13【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.13【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.13【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.11【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.11【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.12【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.12【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.12【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.14【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.14【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.11【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.15【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.14【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.15【初中部 NOIP提高组 】模拟赛C题解
- 2016.08.15【初中部 NOIP提高组 】模拟赛C题解
- ParcelableGenerator将任意对象转化为Parcelable类型
- UVA-644 Immediate Decodability
- oracle数据库中的函数依赖
- Java--数组转成list,list转数组
- myeclipse2015 1.0破解
- 2016.07.13【初中部 NOIP提高组 】模拟赛C题解
- 字符串的排列组合问题
- iOS 25个性能优化/内存优化常用方法
- define和defined区别
- lower_bound()返回值
- CDH5: 使用parcels配置lzo
- 安卓微信支付遇到的问题及解决办法
- oracle基础教程:数据库的范式
- 字符串和数字相互转换