首页 > 代码库 > 二模 (12)day1

二模 (12)day1

第一题:

题目大意:

有N颗糖,两个人轮流取,每次只能取质数颗,不能取的输。求先取者若必胜,最少需要多少步胜利。(N<=10000)

 

解题过程:

1.看到N的范围比较小,先打个素数表,然后dp即可。

2.F[i]表示i颗糖,先取的人若必胜,最少要多少步胜利,若必败,最多多少步失败。如果i减去一个质数可以达到一个必败态,那么必胜,反之必败. 

初始得分80,数据坑爹,说小于10000的,却有20000的数据。

 


 

 

第二题:

题目大意:

有一种虫子,长度为X的时候,一天后会分裂成长度为X-1,X+1的2只虫子。但是不会有长度为0的虫子。一开始有1只长度为1的虫子,求N天后有多少只虫子。  N<=10000.

 

解题过程:

1.直接正面来做估计是不行,就先打了个表,结果发现了10 20 35 70 等数字,就是常见的组合数,然后就找到规律了,答案就是

C(n,n/2).  求组合数为了避免乘法,可以求出分子分母的每个质因子的个数,然后约分。

求n!的质因子,有下面2种方法:

A:直接把1~n所有数分解质因数.

B:利用一个定理:n!中质因子r的个数有 n/r + n/(r2) + n/(r3) + n/(r4) ...... 证明就不说了。我之前的博文有,给个链接:http://www.cnblogs.com/vb4896/p/3968994.html

显然利用方法B要快得多。

原题N的范围是100w(估计是多打了2个0).. 如果用O(n)的欧拉筛法+上面的方法B+高精度8位一压 也只能做到10w的数据0.3s以内跑出来.对于100w的数据就真心无能为力了,接近一分钟~~~(30w位的变态数字...).

2.下面给出为什么答案是C(n,n/2)的证明(考试的时候没时间去想):

首先问题可以转化为求01串的个数,满足它的任意前缀中1的个数不小于0的个数.(0表示长度减一,1表示长度加1,长度不能为0)那么可以用到day1 T1 里的结论:http://www.cnblogs.com/vb4896/p/4037458.html

由n个0,m个1组成的这样的01串的个数为C(n+m,m) - C(n+m,m-1).

那么这题只要枚举0的个数分别是0,1,2....n/2.

0个0的方案数:C(n,0)

1个0的方案数:C(n,1)-C(n,0)

2个0的方案数:C(n,2)-C(n,1)

......

n/2个0的方案数:C(n,n/2)-C(n,n/2-1)

全部加起来就是C(n,n/2)了.

初始得分100.

 


 

 

第三题:(非常综合的图论题)

原题:笨笨大学的专业是电气信息类,这天他又在家里摆弄电路了。这个电路分为3个部分,最左边是一些杂乱无章的N个点,编号为1-N,其中1号点是输入信号发出点。它们互相之间可以用某长度的电线连接起来,一个结点上可以接多根电线,但是电线不能在非结点处相接,另外,它们还可能与第2部分的点通过电线相连。第2部分是整齐的一竖排M个信号放大器,编号为N+1~N+M。它们互相之间没有连接,但可能与第

1部分或第3部分的点相接,如果它们与1号点相连(直接或者间接),则可以输出数字信号1,否则输出0。第3部分的点是T个门电路,编号为N+M+1~N+M+T。每一个门电路有两个输入端,一个输出端,输入端与某个放大器或编号比它小的门电路的输出端相连(这一部分的连接其实是一个有向无环图)。输出端的值是将两个输入的数字信号进行异或运算得到的结果。编号为N+M+T的点的输出端连接到最后的输出,现在告诉你最终输出结果,以及节点之间可用来连接的电线情况,要求你怎样用最短的电线得到这个最终输出,另外最终输出的门电路即(N+M+T号节点)必须与输入信号发出点(1号节点)连通。

 

N≤l00,M≤100,T≤5000,W≤12000

 

题目大意:

有N个点(称为A类点),编号1~N,可以用线(无向边)连接起来,只有点1的信号是1,信号可以传递.

有M个中转点(B类点),编号N+1~N+M,T个门(C类点),编号N+M+1~N+M+T,每个门的输入端连接着编号比它小的两个点(可以相同,可以是B类点和C类点).

B类点如果和1连通,输出信号就是1,如果不连通输出信号为0.

C类点的输出信号为输入的2个信号xor后的结果。

给出B,C类点的连接情况, 现在要你从W条连接 A—B 或者 A-A 的无向边中选一些,使得1号点和N+M+T号点连通,并且N+M+T点的输出信号为k(0或者1),且费用最小.

 

解题过程:

1.题目的限制条件很多,但是有很明显的阶段性,及BC类点之间 AB类点之间应该是分做两个不同的子问题的。睡了个午觉顿时有了思路...最关键的突破点还是要发现下面这个性质(本题的第一个难点):

对于一个B类点,如果它到N+M+T点(方便起见,后面称其为终点,点1为起点)有奇数条路径,那么改变它的信号就会改变终点的信号,如果有偶数条就不会改变. 因为如果改变了一个点的信号,从它开始往后走能到达的点都会被改变一次.显然只有被到达奇数次的点 才会改变信号。 这样就可以把B类点分成3类,一类是到终点有奇数条路径的,称为”有效点“,一类是偶数条路径的,称为"无效点",剩下的是没法到达终点的,是”废点“,直接忽略掉就可以了。

2.如果终点的信号是1,那么根据贪心的原则把一个有效点和起点连起来就好了。如果信号是0,那么有2种情况:一种是取一个无效点,一种是取2个有效点。

3.本题的第二个难点就是取2个有效点的情况。 也就是有一个起点,2个终点,把起点和2个终点都连起来的最小费用.  设2个终点分别为x,y,显然起点到x的最短路+起点到y的最短路是错误的,因为2条最短路可能会有重叠的路段,那么这些路段费用就算了2次.  题解里没给出做法,我的做法是先跑一边floyd,然后枚举到x,y的路径在哪个点第一次分岔.容易证明最优解只可能有一个分岔点。假设有多个分岔点,那么对于任意两个分岔点之间的2条路,如果费用一样不影响结果,如果费用不一样,显然不如合并到费用小的那一条.  

4.所以算法就出来了:先dp出终点到所有B类点的路径数,给B类点分类。根据k是0和1分别计算。如果k=0,还需要枚举选哪2个有效点,并枚举分岔点。 总的复杂度为O(N^3+T).

样例有错,还以为是题意理解错了,就放弃治疗了,没有调试代码.结果题意是理解对了,算法也对了,自己程序细节写错了...0分.

 

总结:

1.空间利用不要太抠门,只要不超内存,尽量数组开大些。

2.对于数字很大的题目,很明显递推要超时,可以先把小数据打个表,然后找规律...而规律一般也就是倍数关系,或者斐波那契数列,或者组合数,或者Catalan数,尽量多试一试。比如T2.

3.复杂的题目往往可以划分成几个子问题,应该逐个解决,降低思维的难度。比如T3.

4.代码写好一定要仔细调试,宁可不写,也不要写了一大堆却暴零。

5.许多结论不仅要记住,还要理解是怎么推导过来的。比如昨天T1的公式,如果以前没有花了一个晚上好好琢磨过Catalan数的推导绝对想不出来。不会推导,只记结论,题目一变就挂了。

6.一定!!要多看NOI导刊!!

二模 (12)day1