2013 蓝桥杯 全国软件大赛 c/c++ B组 决赛 第 五题

来源:互联网 发布:js 编辑器 编辑:程序博客网 时间:2024/05/02 12:30

小记:这次的北京之行,让我受益颇深。这次比赛,个人觉得 题目出的 还是有欠考虑,因为前三题 和后三题的难度 差距着实有点大。 就后面的三题,比赛的时候我只做了一题,那就是第五题,最倒霉的是还是最后一刻想出来的。唉,能力还有待加强,大家一起努力吧。

第五题的题目是:

下面我讲讲我的第五题思路:

所有的可能就是将 以每个点为终点 有多少种刷法(以end[]表示) 的种数相加起来就是要求的数,记得取模就行。

那么,我们只要求出这个2*N的矩阵的N/2的点 以他们每一个点为终点有 多少种刷法 然后 将这些点的相加乘以4就是总和。

1 3 5 7 9

2 4 6 8 10

假设这是一个2*N N=5 的矩阵,数值表示是第几块,方便等下说清思路。

我们先要求出四周的四个点的end[],因为对称,所以只要求出一个点就行了。

我们就选第10个点好了。

那么以10为终点,那么10前面的一个点可能就有7,8,9.

而如果先把10去掉,那么以9为终点的end[9]的值就等于end[7]|+end[8],因为此时在9前面的一个点只能是7,8.这个时候因为已经确定了最后两个要刷的是9和10,所以,就可以看成是2*N N=4的矩阵里面的求end[],而这个我们可以假设它的end[]已经算出来了。那么我们就直接引用就行。所以9-10这条边已经知道了。

那么如果10前面的一个点是7和8,因为7,8是对称的所以只要求一个的end[]就行,注意这里的end[7],end[8]是包括了9在内而不包括10的。

我们就算以7为终点的就行了。

以7为终点,那么它前面的一个点就可能是5,6,9,这3个。如果前面是9,那么就是2*N N=3时的 end[5]+end[6]。

如果前面是5或6,那么只要算出一个就行了,我们就算5好了。因为去掉7的话,5是最后一个要刷的点,那么我们就必须从9开始刷,然后刷8,再是在一个2*N N=3的矩阵里以6为起点,以5为终点的可以刷的种数(以后就用st[3] 表示,这个我等下会讲怎么求。),所以就是st[3]种。

到这里,我们已经求完了。此时:end[10] = end[7] + end[8] + end[5]+end[6] + 2*st[3]

进行推广就能得到:end[i] = 2*end[i-1] + 2*end[i-2] + 2*st[i-2]

在一个2*N N=3 的矩阵中,以6为起点以5为终点,它的刷完的种数有2^N-1种。

因为以6为起点了,那么终点5前面的一个点只能是3或4,因为3,或4对称,所以就变成了2*st[2].

因为2是系数,所以推广得出st[N] = 2^(N-1)

现在还有问题就是 中间的那些点怎么求他们的end[].

假设我们现在是在2*N N=5的矩阵里求第7个点的end[7]。

那么我们知道它的刷法 必定经过第8个点。所以这一列把整个2*N的矩阵分成了两个一个是2*(i-1)(i表示当前的列),另一个是2*(N-i)

那么他的刷法必定是这样的:

以2*(i-1)的最右边的两个点的某一个点为终点,然后经过8,然后再是以2*(N-i)的最左边的两个点的某一个点为起点,另一个点为终点,然后到达7.或者反过来,

这样我们可以看到这中间需要求的我们都已经求过了。所以递推可得解。

end[i] = 2*end[i-1] * 2 * st[N-i] + 2*end[N-i] *2 * st[i-1]

到这里我们中间的点也算出来了,此时记得将2*N 的矩阵分成4块,如果N是奇数等下加上两个中间的就行。每一个块的总end[],由上面的式子可以求出。大伙自己动手算出这个吧,不然你也不会明白这是怎么算的。

这题基本就差不多解决了。从难度上来看,确实比较费力。我提交上去的这题的代码是先打表,最最关键的问题是 我都没经过编译的。就直接交了。可伶的我啊、、、、、

代码 很简单,基本就是递推,我就不再多写了,很伤心啊、、、、、、、、、、、、



其他题再说吧。

原创粉丝点击