转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove
题目链接:http://acm.hfut.edu.cn/OnlineJudge/ 题号:1299-1310
唔。。。因为和长沙邀请赛冲突了,就只能让一些小朋友们去省赛了~~~~
比赛结束之后,听说省赛挺惨的(大概是意料之中吧)
不过意料之外的是,12道题,夺冠队5题,其它队伍最多4题。。。无法直视
回到学校之后,终于等到了题目。。。。
花了一天的时间,终于水过了所有的题。。。在官方题解还没问世的情况下,先来骗点访问量
A:字符串处理(水题)
找到单词,反向输出。。。没啥好说的
B:线段树
首先记录每个数与前面一个数的差值。形成一个序列
那么最长的等差数列,便是区间内最长连续相同的子序列。
这便成了一个序列,可以区间修改(加、减),然后查询某个区间内的最长连续相同子序列。
修改操作的话,[l,r]进行(A,D)的操作。相当于a[l]与a[l-1]的差值增加了A。[l+1,r]的每个数与前面一个数的差值增加了D,而a[r+1]与a[r]的差值增加了-(A+(r-l)*D)。三段区间修改。
至于怎么维护区间的查询。首先对于区间的更新,肯定需要懒惰标记lazy。
然后需要记录整个区间是否是同一个数cover,如果是-inf,说明整个区间不是同一个数//好像这个变量没啥用TAT
记录最终答案整个区间的最长连续len。
在区间合并的时候,两个区间合并,相邻部分可能合成新的部分。
所以需要记录一个区间两端的情况。
左端点的什么数字left_num,以及左端点连续相同个数left_cnt
右端点同理right_num,right_cnt。
push_up()的时候,对于cover,如果两个子区间cover都不是-inf,而且一样,说明整个区间是同一个数,否则-inf。
对于len,肯定是max(左区间的len,右区间的len,左区间的右部和右区间的左部)。
对于left_num,肯定是左区间的left_num。right_num肯定是右区间的right_num。
对于left_cnt,肯定是左区间的left_cnt,以及左区间的cover便是left_num,说明可能和右区间的left_cnt合并。
同理 处理right_cnt。
查询的时候,可以是左区间的lef,右区间的len,还可能是两个区间的邻界处,注意left_cnt或者right_cnt可能超过区间长度。
C:排序,模拟(水题)
按到达时间排序,然后模拟
D:几何
大意是说有一个点,一个圆,一条线段,求圆上一点到点的距离以及到线段的距离之和最小。
圆上肯定只有一个单峰最大和单峰最小。。。然后就打算用三分解决,但是这和三分写法有关,怎么样处理类似的一个周期函数比较纠结。。。。
尝试几次WA之后,只能枚举角度水过。。。。坐等正解。
枚举圆上的点。。求点到点的距离,以及点到线段的距离。
正解是分为(0,pi) (pi,2*pi)两段去三分,那么每个区间里不同时包含最大值和最小值,就可以三分
E:二分+半平面交
大概就是在一个凸多边形内找到一个半径最大的圆。
二分半径,然后将凸多边形的边向内推r。半平面交判断是否新多边形是否存在核。
F:模拟
不能多说。。。大概就是使劲模拟,考虑所有情况,细心点就行了
G:博弈
这场的博弈题还是挺神的。。。。
首先判断一下先手是否能胜。可以知道先手如果想要胜的话,至少需要m件物品。如果自己的钱连每一件物品都支付不了1个单位价钱的话,需要特殊判断。如果对于的钱多于自己,显然对方胜,如果钱一样。则每人花1个单位价钱买走一个物品。最终打平。
对于钱很多的情况,知道想要拿下m件物品的话,平均每个物品需要支付多少钱。取下整之后,将剩余的钱加在某些物品上。然后依次出价,这时候对于对方来说,必须尽可能阻止先手的所有报价。即只要手上的钱超过对方的报价,就要竞价(当然多出1个单位就行了)。因为对方知道如果先手的所有报价都能成功的话,对方便赢了。
如果先手无法胜利,则要判一下是否为平局。同理 还是求一下至少需要赢m物品。将自己的钱平分在m件物品上,后手阻止先手的报价。
当然主要是细节需要考虑。首先我一直WA在n==0的情况。。。不能多说,OJ竟然不返回RE。
另外就是钱不足以支付每一件物品的时候。也就是存在某些物品没人竞价的情况。
H:高精度+排列
挺无聊的数据范围,完全没有必要让别人用高精度吧= = 。
又不让用JAVA,我又没有高精度模板,百度了一个还是错的(自己debug出来。。。)!!!!
做法大概是先统计一下当前这个排列是处在全排列的多少位,然后前推后移之后,就是输出第K大全排列了。
I:最短路+DP
先从终点出发,预处理出所有点到终点的最短路。
然后从终点记忆化搜索,统计一下方案数。
J、K:推理
好多人不理解游戏规则,以1,2,3为例,三个人分别人a,b,c。
那么第一轮a觉得自己可能是1,可能是5,b觉得自己可能是2可能是4,c觉得自己可能是3可能是1。所以 无法判断,他们的答案是否。
第二轮c已经能猜出自己肯定是3了。因为假设他是1的话,那么第一轮中b看到的两个数字是1和1,但是由于题目说了是正整数,即不可能是0,那么b应该能猜出自己的数字。但是第一轮中b没有猜出,那么c就可以否定掉自己是1的可能。
首先你需要YY出是数字最大的那个人先猜出数字。。。我只能YY,猜想,瞎搞。
那么对于(a,b,c)a<=b<=c来说,对于c正解是b+a,现在需要求他能在多少轮之后否定掉自己是b-a的可能。
那么现在的三元组成了(b-a,a,b) 当然也可能是(a,b-a,b) ,同理还是最大的一位去否定掉另外一种想法。
直到a==b,说明这时候已经出现了矛盾。
每次去减肯定过不了K的大数据。可以观察发现最小的两个数就是辗转相转法。。转化成(b%a,a,b)+b/a。
L:树DP
两次树DP,up[i]表示从i这点,向父节点传的期望流量 ,down[i]表示对于i这点,父节点向i传的期望流量 。
up的包括两部分,首先是除了根以外的结点,结点本身的一个流量可以传向父节点。概率便是1/节点的度。
另外一部分便是孩子节点up到当前节点的,可以继续up,但是注意这里不能往 回走,所以概率是1/(度-1)。
之后是求Down,down的分为3个部分,结点本身可以down。down给父节点的部分,可以继续down给孩子结点。
从非当前孩子结点up到父节点的流量可以down。
处理的话,以1为根,但是1可能也为叶子,那么1的流量 便是根的孩子up给父节点的流量 。其它叶子为down的流量 。
code:https://github.com/cxlove/ACM_ICPC/tree/master/Contest/AnhuiProviceContest_2013