zoukankan      html  css  js  c++  java
  • 2013年安徽省省赛题解(山寨版)

    转载请注明出处,谢谢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之后,只能枚举角度水过。。。。坐等正解。

        枚举圆上的点。。求点到点的距离,以及点到线段的距离。


    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的流量 。









  • 相关阅读:
    深入浅出JMS(二)--ActiveMQ简单介绍以及安装
    redis学习
    浏览器的渲染过程
    http请求
    常用正则表达式
    js继承的几种实现方式
    js中的浅拷贝和深拷贝
    webpack常用的plugin
    linux基本命令
    webpack压缩代码组件uglifyjs-webpack-plugin
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3108968.html
Copyright © 2011-2022 走看看