20170318胡策

来源:互联网 发布:如何评价沈光远 知乎 编辑:程序博客网 时间:2024/05/16 07:02

T1
这里写图片描述
这里写图片描述
T1知道方法以后当然是一道zz题,但是考场上并没有想出来。一开始以为子序列是必须连续的,然后开始瞎搞,还想用后缀数组的思想(虽然我并不会写后缀数组)。
考试一段时间后,出题人说子序列是可以不连续的,然而我并没有听见,直到考试结束钱不到半个小时才明白过来,于是写了一个dp(鬼知道我当时是怎么想的),感觉思路非常正确。
这道题的正确思路是用单调队列求解。每次算出一个数就扔到单调队列里,算到第i(i>=n-k+1)以后就每次输出队首。其实代码非常简洁:

#include<cstdio>int q[1500000];int x,y,z,n,k,h,t;int main(){    freopen("red.in","r",stdin);    freopen("red.out","w",stdout);    scanf("%d%d%d%d%d",&x,&y,&z,&n,&k);    for(int i=1;i<=n;i++)    {        while(h<t&&q[t]<x) t--;        q[++t]=x;        if(i>=n-k+1) printf("%d\n",q[++h]);        x=(1ll*x*y%z)+1;    }    return 0;}

T2:

这里写图片描述
这里写图片描述
这里写图片描述
这道题我当时写了一个大爆搜,然后写炸了。。样例输出是错的,应该是1,但是当时出题人说的时候我没听到,把答案除以二就能过3个点。
有两种可以得到60分的dp做法:
先放一个图:
这里写图片描述
题目中的出发点和结束点在图中的S和T点,所以当从出发点第一次移动时,一定会到达A或者B点。同理,当即将到达结束点的时候,一定会到达C或D点。既然题目要求两次路线不能相交,那么如果有一条路径从A点出发、D点到达,或者从B点出发、C点到达,那么一定是会交叉的。
正确的走法只有两种:从A出发、C到达,或者从B出发、D到达。
那么如何求总方案数呢?可以想到,所有有可能的正确走法数目是从A到C的方法数乘从B到D的方法数,减去从A到D的方法数乘从B到C的方法数。
还有一种求法:我们可以联想到方格取数这道题,只需将路径中经过的点的价值总和改成到达该点的所有合法路径条数就可以了。但是需要注意一点:答案要除以2,因为两次走的顺序相反会被计算两次。

T3:

这里写图片描述
这里写图片描述
这里写图片描述
这道题我也写的暴力,然而写挂了,只得了10分。题解中用到了莫比乌斯反演,然而并不会。貌似还有一种方法可以不用反演,但是化简等式没有看懂。

总结:

自己做的题还是太少,有时很简单的题没有看出正确解法;
建立数学模型的能力还是太弱,无法转化出模型解决;
暴力写得太差,要多加练习;
内心还是不够强大,但是又很浮躁。这样怎么迎接即将到来的省选呢?感觉第一轮就被刷下来的可能性很大,毕竟省里高手那么多,想要挤入前几十名实在是太难了。况且,自己的联赛成绩也不怎么样,有可能连省选的资格都打不到。

现在以及以后一定要多刷各种类型的题,争取练出能用比较短的时间看出题目的考察内容,并且提高自己的代码功底;学习常用的算法和数据结构。
路在自己脚下,走一步就离目标近一步。

0 0