第一题:
题目描述:
一个阅览室每天都要接待大批读者。阅览室开门时间是0,关门时间是T。每位读者的到达时间都不一样,并且想要阅读的刊物不超过5本。每位读者心里对自己想看的刊物都有一个排位,到达之后他会先去找自己最想看的刊物,如果找不到则去找其次想看的刊物。如果找不到任何他想看的刊物,他会开始等待,直到有一本以上的他想看的刊物被人放回原处。当然,他会先去拿其中自己最想看的刊物。当他看完某一本刊物后,就把它放回原处,接着去找自己没看过的最想看的刊物。如此下去,直到看完所有他想看的刊物为止。矛盾出现在两个人同时想要拿同一本刊物的时候。阅览室为了避免读者之间出现争执,作了一个规定,读者每次在开始等待时先去服务台做一次登记。如果两个人都同时想要一本刊物,那么先登记的读者将得到这本刊物。如果两个人同时登记,那么先到达阅览室的读者将得到刊物。没得到的人就只能去找其他的刊物看。阅览室关门时,所有读者都将被强迫离开阅览室,不再允许继续阅读。
现在阅览室想做一个统计调查,你被要求写一个程序来模拟这个过程计算出所有刊物被阅读的总次数。当某个读者开始阅读某本刊物时,该刊物的被阅读次数就加1,无论这本刊物最后有没有被读完
解题过程:
1.蛋疼的模拟题,题目不大好理解,而且没有说明两个人同时到达且要同一本该怎么办(数据里没有这种情况)。
2.其实这题认真去写也不是那么恶心.主要是想明白如何处理 ”登记“操作. 我用了一个ok[i]数组,表示编号为i的书空闲下来是在什么时候。根据时间来模拟,如果当前时间有一个读者来了(arrive_time=cur_time),以此检查他能否找到一本可以看的书(ok[i]<=cur_time),把那本书的ok[i]加上一个他看书花掉的时间t,并可以假设那个人把书带回家看了,所以把那个人的到达时间arrive_time加上他看书花掉的时间t(可以想象成他把书带回家看了,看完了瞬间回到阅览室了)。
3.如果一个人找不到可以看得书,那么依次检查找到一本他还没看过的且ok值最小的书(假设编号为k),然后就可以想象成他先回家了,然后到时间ok[k]瞬间回来了,又把那本书带回家看了,所以ok[k]+=t . 这里要注意ans++的条件必须是未更新前的ok[k]<T。这样就完美地解决了冲突和登记的问题。
初始得分100.
第二题:
题目大意:floodfill 求出四联通块的个数和每个联通块的floodfill时间。
解题过程:
1.直接BFS实现floodfill即可。题目没说清楚被坑了一次,题目的本意是从最左边的一列开始,从上到下,从左到右。也就是
(1,1)->(2,1)..理解成(1,1)->(2,1) 了。。
初始得分30.
第三题:
解题过程:
1.一开始想的很复杂,结果到最后还发现我的dp方程有后效性. 于是就只有30分了。。
2.看了题解,最巧妙的地方还是图的转化:
从左到右做dp,F[i][j]表示前i列放了j个且第i列必须放的方案数。那么有:
F[i][j]=sum{ F[k][j-1]*(len[i]-j+1) }。
因为前面放了j-1个,所以有j-1行被控制了,因此第i列只有len[i]-(j-1)=len[i]-j+1 个 地方可以放。
最后统计答案ans=sum {F[i][tot]}。
3.第二题提交有一个点挂了。因为上面的方程是无法处理 tot=0的情况的。。所以要特殊处理。