北师大珠海分校第十六届IT节网络预选赛题解

A.分不分

题意:
    找一个 a + b = n, 且 a / b 最简和最大。
题解:
    大多数人都错在了真分数上,不了解自行百度。
    要取 a / b 最大,一定是从 n 的一半开始取,所以从 n / 2 开始左右遍历判断是否符合条件(即 a 和 b 互质为最简分数),符合直接输出。

B.橘猫与千层糕

题意:
    有n个千层糕,从每一个千层糕的[a, b]层中选取一层,把所有层数相加刚好可以被5取模,问这个选取有多少种情况。
题解:
    当我们拿第一个千层糕的其中一层,那么我们可以得到余0、余1、...、余4的所有答案。当我们要拿第二个千层糕的其中一层,假设我们选取的层数模5余1,那么它和前面余0相乘可以获得余1的答案,它和前面余1相乘可以获得余2的答案,同理可以获得所有余0、余1、...、余4的答案。
    因此我们可以设计一个dp公式:dp[i][j](其中i代表拿第i个千层糕,j代表拿了其中一层模5余j的种类,一下mod0表示[a, b]中可以被5取模与0的个数,同理mod1、...、mod4)
    dp[i][0] = dp[i][0] * mod0 + dp[i][1] * mod4 + dp[i][2] * mod3 + dp[i][3] * mod2 + dp[i][4] * mod1;
    dp[i][1] = dp[i][1] * mod0 + dp[i][2] * mod4 + dp[i][3] * mod3 + dp[i][4] * mod2 + dp[i][0] * mod1;
    ...
    dp[i][4] = dp[i][4] * mod0 + dp[i][0] * mod4 + dp[i][1] * mod3 + dp[i][2] * mod2 + dp[i][3] * mod1;

C.橘猫吃千层糕

题意:
    求数组中的中位数,如果是偶数个,则取中间两个的平均值。
题解:
    直接排个序,奇数个取中间值,偶数个取中间两个和的平均值。
    题目中说数据在int范围内,那么偶数个取平均值时候相加肯定会爆int范围,可以两边各取一般,其他方法也可以。

D.Erwin Schrödinger的橘猫

题意:
    有n个密码,有m个猜测密码。如果猜测密码的长度小于或等于密码且是其中一个密码的前缀,或者测密码的长度大于密码且其中一个密码是猜测密码的前缀,就可以输出“YES”,否则输出“NO”。
题解:
    解法多种,只说一种。
    构建一个结构体,里面存储[0,9]的结构体数组,链表形式进行建十叉树,将密码从头遍历存储在结构体链表中。当我们去查询猜测密码是否符合条件时,可以从树根搜索,到没有分支或者猜测密码结束时则符合条件,否则不符合。

E.星澈的脸盲症

题意:
    有一个长度为2*n-1的数组,找出其中只存在一次的元素。
题解:
    数据范围比较小,可以用一个长度为1000的数组记录[1,1000]中某些元素出现次数,之后遍历一次数组,输出只出现一次的数。异或,排序等方法都可以。

F.灭霸讨厌千层糕

题意:
    A1 = 1,A2 = 2,A3 = 5*A2 + 3*2*1,...,An = 5*An-1 + n*(n-1)*(n-2)。
    B1 = 1,B2 = 3,B3 = 4*B2 - B1 + 2*1,...,Bn = 4*Bn-1 - Bn-2 + (n-1)*(n-2)。
    输出An - Bn。
题解:
    An = 5*An-1 + n*(n-1)*(n-2);
    An-1 = 5*An-2 + (n-1)*(n-2)*(n-3);
    n*(n-1)*(n-2) = (n-1)*(n-2)*(n-3) + 3*(n-1)*(n-2);
    n*(n-1) = (n-1)*(n-2) + 2*(n-1);
    n = n-1 + 1;
    因此可以构建右矩阵为:

    \begin{bmatrix}An-1 \\ n*(n-1)*(n-2) \\ (n-1)*(n-2) \\ n-1 \\ 1 \end{bmatrix}

    Bn = 4*Bn-1 - Bn-2 + (n-1)*(n-2);
    Bn-1 = 4*Bn-2 - Bn-3 + (n-2)*(n-3);
    n*(n-1) = (n-1)*(n-2) + 2*(n-1);
    n = n-1 + 1;
    因此可以构建右矩阵为:

    \begin{bmatrix}Bn-1\\ Bn-2 \\ (n-1)*(n-2) \\ n-1 \\ 1 \end{bmatrix}

    因为有一样的代表数据可以构建右矩阵:

    \begin{bmatrix}An-1 \\ Bn-1\\ Bn-2 \\ n*(n-1)*(n-2) \\ (n-1)*(n-2) \\ n-1 \\ 1 \end{bmatrix}

    根据上面给出的公式,构建左矩阵:

    \begin{bmatrix} 5 & 0 & 0 & 1 & 0 & 0 & 0\\ 0 & 4 & -1 & 0 & 1 & 0 & 0\\ 0 & 1 & 0 & 0 & 0 & 0 & 0\\ 0 & 0 & 0 & 1 & 3 & 6 & 0\\ 0 & 0 & 0 & 0 & 1 & 2 & 0\\ 0 & 0 & 0 & 0 & 0 & 1 & 1\\ 0 & 0 & 0 & 0 & 0 & 0 & 1 \end{bmatrix}

    因此,矩阵相乘可以得到下一个An和Bn,相减就是答案。由线性代数的相关知识,左矩阵自己多次相乘再和右矩阵相乘不会影响结果,所以对左矩阵运用快速幂,优化时间。

G.噬元兽与千层糕

题意:
    有1000个千层糕,某些是草莓口味的,让你去掉一些草莓口味的千层糕使得每一个区间长度为m内的千层糕口味不超过k个,求最少去掉草莓口味的个数。
题解:
    贪心题,在[1, m]区间内我们优先删除后面的草莓口味,同理[2, m+1]、...、[n-m+1, n]都是优先删除后面的草莓口味。所以遍历一遍记录要删除的个数即可输出答案。

H.阿柴的千层糕

题意:
    求区间内不同数的和。
题解:
    莫队算法模板题(线段树+离线也阔以)。
    离线处理区间,通过mark标记出现的数并记录次数来维护区间和。
    注意,要离散化数组的数,如果有其他办法记录也是OK的。

I.猜猜我是第几名

题意:
    制作一个简单模拟OJ排名的程序,输出某个人的排名。
题解:
    可以构建一个结构体来存储一个人的状态,比如:姓名、过题数、罚时等。
    将结构体按照过题数优先罚时其次的规则排序,遍历一次名字输出名次即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章