ACM-ICPC 2018全国邀请赛(陕西西安)

时间:2021-03-03 22:55:18

一、火车晚点

星期五下午4.36的火车,我们3点到了长沙火车站。差不多4点了,提示,晚点1h45min,DZC马上说,不知道会不会延误郑州到西安的那趟车。过了一会,又提示,晚点2h17min,再过一会,又提示,晚点2h10min,后来一直变来变去。我们当时就决定,晚上10点左右如果还没到武昌,就要考虑改签了,并选好了下一班改签的车。期间,DZC一直在和他爸爸打电话,真心觉得,他爸爸还是非常非常关心他的。终于火车来了,还是晚点2h17min。进入车厢时,乘务员收走了车票,我说了一句,怎么把车票收了?他回答,等下会给你们换(【捂脸.jpg】,原谅我第一次坐卧铺)。第一趟火车上,迷迷糊糊睡着了,期间DZC很给力,一直在操心着能不能赶上下一趟车问题。中途他去问了列车长,说如果延误,可免费改签,因为这是他们的问题。听到着我们三算是心里的石头落地了。那趟车也比较给力,居然还争取回10min,在凌晨3:10到了郑州。于是我们匆匆地赶着去换乘,还是赶上了原来订的那趟车。换车后,躺下一会儿就睡觉了。

早上8点醒来,发现已经进入西安的境地了,拉开窗帘一开,确实是一眼望去很平整的感觉啊(第一次去湖南以北的地方)。完全没有湖南的一眼望去全是高山的感觉。虽然也能看到山,但都是很矮很矮的山,总体感觉就让人觉得比南方更平坦。在火车上看了一会儿风景后,队友醒了,然后聊天聊到了下车。

二、酒店

报道完之后,去西工大食堂吃了顿饭,味道还行。有点南方口味。然后坐西工大的校车去了酒店。一进南山酒店的大厅,感觉很香,第一印象不错。然而不错的也只是第一印象。后面发生的事情都让我们非常不爽。首先,一开始让我们坐在酒店前台的沙发上等。等了差不多二十分钟,终于把该弄的手续弄好了。然而,之前网上预定时说好的加床只需要加80元,到了后就说:没有80的说法,都是加100元。【喷血.jpg】。这也就算了。接下来的发生的关于酒店的事,一件比一件恶心。原来真正住的不是那个看起来高大上的招牌建筑,而是后面的,需要步行几百米的一栋所谓的“小白楼”。而那栋楼,我们一走到那,第一感觉像民宿,第二感觉像阴宅。这忍忍就算了。给我们开的房间,居然是一楼入口的第一间。刷卡刷了两三次才打开门,进去之后,发现只有两个床【一脸懵逼.jpg】。把房卡插进去,发现没电。房间不能开窗户,因为可以直接从外面爬进阳台,再跳进窗户。于是打电话,所有地方能看到的关于这个酒店的电话都打了,没一个是空号的。没办法,只能走回去问前台。前台说,一会儿叫人弄好。回去后,修理工来了,把外面的闸弄了几下,好了,有电了。QJ一开厕所的灯,吱吱吱响了半天,黄色昏暗的灯一闪一闪的,突然又熄灭了,整个房间又没电了。然后修理工又重启打开闸,QJ一开厕所灯,又这样。……,这样反复四五次之后,修理工说让我们先开外面的灯,再开里面的。试了下,貌似没问题了。厕所灯不吱吱吱响了。然后管理阿姨开始加床。我们找插座,找了半天,整个房间就一个插座,还是在桌子底下(【喷血.jpg】)。我向管理阿姨说,要去找个插座过来,阿姨敷衍说尽量,然而后面就一直没有尽量了。床弄好后,管理阿姨走了,我说了句,要是还有事,我会找他们的。两个管理阿姨一脸懵逼,互相对视,我的普通话真的那么难听懂吗???

接下来,出发去打热身赛,QJ说洗个头,去开水龙头,发现连热水也没有。于是只能用冷水洗头了。。。。。。

热身赛回来,一开卫生间的灯,又开始吱吱吱了。DZC打了管理阿姨的电话,管理阿姨叫了个修理工过来,把灯拆掉了,还是吱吱吱。估计修理工也讨厌那酒店的设施了。直接说,这今晚是搞不定了。要把上面的天花板拆开才能修好。然后,管理阿姨说没办法,只能将就,行……吧,将就一下。于是,两人走了。我们已无力吐槽,躺了一会,去外面吃东西了。回来后,没洗澡、没洗头,就草草地用冷水洗了把脸,睡觉了。住的最差的一次酒店。

睡的感觉还可以。一觉睡到了早上。酒店提供的早餐不错。给那酒店挽回了一点好感。

三、热身赛

下午是打DD去学校的。985学校就真的是叼,校门口就是不让进,偏要下去两三个人一起签字才让进。

热身赛开始了。A题是个水题,秒出。B题我没懂题目意思,给DZC看了下,他明白了(真佩服他的读题能力、思考能力和编码能力),想了下并查集,DZC说不行,因为并查集无法快速统计环的顶点个数。后来他想了个二分,写了下,过了。C题像是概率DP+状压DP,我的菜。但是,久了不写概率DP,都有些忘记如何写转移方程的了。后来还是没出。回去后,我在酒店复习了一下概率DP和期望DP。第二天正赛早上,西安邀请赛的QQ群里发了题解,看了下,不是概率DP,没这么复杂。哎,还是水平不够、能力不足啊。

四、正赛

从进入西工大实验大楼机房开始讲。

一进去,立马开机。进入ubuntu,配置了IDE,敲好了输入挂,一切准备就绪。等了好久,账号和密码条终于过来了,密码是:9CUldK。去登PC^2,怎么输入密码都不对,把l换成1和换成l都不对,于是只能去找志愿者。志愿者听了后,说叫人过来帮忙,然而,过了半天也没人来。而此时已经在发试卷了(原谅我用“试卷”这个词,因为那题目真的就是高中试卷,而且一个队还只有一份。当然咯,这影响并不大)。这时,尴尬的事情又来了,我们那机房的好几个队(包括我们)居然没“试卷”。然后,QJ想,是不是要重启电脑才行。然后重启了(之前做的功夫全没了),尝试了各种可能的密码,还是登不上PC^2。于是我第二次去找志愿者了,志愿者回复还是那样,找人给我们解决。这时我们队的“试卷“终于来了,只有一份。于是分开读题,我读ABC,DZC读DEF,QJ从后面开始。DZC反应很快,看到E是个水题,马上敲完了。但是登不上PC^2。只能等志愿者所谓的叫人来。开场大概15min后,场上一大堆过E的队伍了,手速快&脑子灵活的过了A和E了,而我们连PC^2都登不上去。突然,QJ说,K是大写的,我和DZC【捂脸.jpg】,试了后,登上去了。立马交E,No-WA。然后QJ和DZC开始调E,我也想清楚了A的写法了。准备马上敲A。这时,志愿者所谓的叫人来,终于来了,说给我们改了密码,我们仨【捂脸.jpg】,我们说已经登上去了,于是helper balabala半天后,说,那行,给你改回来。然后,我们算是正式开始比赛了。DZC让QJ改了下代码后,交,Yes。我立马敲完A,No-WA。想了半天,感觉没错,给DZC讲了我的思路(统计a和b的二进制表示中0的个数ca0和cb0,1的个数ca1和cb1,然后答案就是min{ca0 + 1, ca1 - 1, cb0 + 0, cb1 - 1})后,他也绝对没错。想了大约15分钟,DZC突然想到了反例:1000001111100000(2),只需要一次+操作和一次-操作。我听了后,是由衷地佩服他啊。然后,换DZC去敲A,我手动把上面的二进制转成十进制,敲完后,测了样例没错,交,Yes。然后,QJ和我讲了K的题意后,我想了下,我说,线段树节点维护三个值,“节点和,增长量, 延迟标记”。但是,这在下推的时候非常不方便,而且,在极端的情况下,单词查询的时间还是O(N)。然后,QJ不太明白,开始翻板子,DZC开始看D,我看C。然后开始敲。敲了个时间复杂度O(NQlog2N)的代码后,交一发,No-TLE。(后来在回韦曲南地铁站的西工大校车上,我问了下他一开始写的那个代码的时间复杂度,他说O(NQlog2N),我说我暴力都只需要O(NQ),你的代码比暴力还慢,他【捂脸.jpg】)。DZC看完D后,开始和QJ讲。讲完后,两人觉得没错,敲。交上去,No-WA。然后我DZC讲C题的题意,我说,这看来看去没啥坑,直接暴力就行了。DZC看了下榜,C题,104 Submissions,5 AC。然后开始找题目的坑,反复看了两遍题目后,我还是觉得没问题。DZC突然说,题目没说按输入顺序卖石头,我想了下,觉得,非常有道理。然后我们俩开始想这个题。尝试各种转背包问题,还是感觉没法转,于是,我继续想,他继续调D,QJ仍然干K。感觉想了大概半个小时后,写了各种DP式,然而,都没用,感觉这个题目的DP与买卖石头的顺序有关,无法表达最优子结构(主要还是我能力差,这题应该是个DP)。然后,看了下榜,发现G题过的人很多,DZC告诉我题意后,我和他说,直接集合去重不就行了,DZC说会炸浮点数精度(事实证明也确实是这样),然后我说,那就把浮点数放大,变成整数。DZC当然不明白set的去重原理,说这样应该还是不行(事实证明正解就是这样做)。然后,我想了下,觉得如果不这样,那就只能用分数表示浮点数。我让DZC给我手推一下直线焦点方程,他推了一会儿后,感觉式子越来越复杂,不推了(主要是受一开始的密码条和D题的影响,心态很浮躁了)。我说,那就直接用浮点数吧。赌一把。DZC纠结一会儿后,行吧。然后,我开始找几何模板(真是现学现用啊,以前从来没敲过几何),敲完后,测了下样例,发现不对,然后我开始调bug。DZC手画直线,发现几何模板找出来的点和手画出来的差太远太远。我继续调,把精度改为1e-3后,答案仍然不对(实际上应该改为1e-1才能对)。然后我换了个几何模板,敲完后,测样例,仍然和之前的结果一样。这时不怀疑模板了,而是开始怀疑思路了。我突然把精度改成了1e-1,答案对了,测一下其他样例,也没错,交上去,No-TLE。然后,意识到浮点数的运算速度了,真的是慢。然后,我开始尝试各种优化,输入加速挂,set换map,仍然No-TLE。于是我说,把set改成unordered_set试一下,编译通不过,没有重载point结构体的哈希函数,然而我们又不会(要是会,那应该就过了)。于是,只能眼巴巴地坐在那了,真是没法优化了。这时DZC说,那就写分数类,但是,重载+法运算符的时候,发现通分很麻烦,如果用gcd函数,时间复杂度又退化,于是就弃了。而这时,已经封榜了(4个小时过的真是迷迷糊糊,都不知道怎么过的),而此时我们的D还是没出(还是实力差啊)。然后,我换了个题,去想E,并没有想清楚,就开始按照一开始的思路敲线段树了,越敲越乱,我写不下去了。然后,DZC和QJ终于找到D题的规律,改了改代码,过了。然后我的线段树敲不下去了,三人开始吃面包了。比赛结束了。

果不其然,只拿块铜。感觉拿银是没任何问题的。因为可做题都够拿金的数量了。但是呢,可做不一定可AC啊。因为姿势不够,学的不够深。其实如果我能出C题,那就稳银了。但是我搞不定啊。所以,我感觉,真有愧于队友。

五、回家

领奖完之后,校车把我们送回韦曲南地铁站。就此就算完全和西工大别离了。在路上,买了点樱桃吃。味道不错。西安的樱桃相比其他地方,真是便宜好多好多。然后,晚上在北大街地铁站和回民街附近吃了东西,稍稍逛了一下,感觉挺不错的。有趣的是,在回民街的尽头处,看到了一座城楼,正门顶上的牌匾写着:声闻于天。这不就是我们的队名吗?当时确实感觉很欣慰。之后就去坐火车了。

六、总结

     1、A题,典型的CF题,要多打CF。

2、G题,浮点数去重方法:

(1)放大若干倍,变成long long类型的整数;

(2)使用哈希,C++结构体重载哈希函数。

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;

struct Point{

    double x, y;

    Point(, ):x(x),y(y){}

    bool operator < (const Point &p) const{

        )return y < p.y;

        else return x < p.x;

    }

    bool operator > (const Point &p) const{

        )return y > p.y;

        else return x > p.x;

    }

    bool operator == (const Point &p) const{

         && fabs(y - p.y) < 1e-;

    }

    bool operator != (const Point &p) const{

        return !(*this == p);

    }

};

struct cmp{

    LL operator()(const Point &p1) const{

        return LL(p1.x * p1.y);

    }

};

struct eq{

    bool operator() (const Point &p1, const Point &p2) const{

         && fabs(p1.y - p2.y) < 1e-;

    }

};

unordered_set<Point, cmp, eq> us;

int main(){

    us.insert(Point(3.0, 4.0));

    cout << us.size() << endl;

    us.insert(Point(3.0, 4.0));

    cout << us.size() << endl;

    us.insert(Point(4.0, 3.0));

    cout << us.size() << endl;

    us.insert(Point(4.0, 3.0));

    cout << us.size() << endl;

    us.insert(Point(2.0, 6.0));

    cout << us.size() << endl;

    us.insert(Point(1.0, 12.0));

    cout << us.size() << endl;

    ;

}

3、K题。维护两棵线段树。

  4、两线段求交点。已知两线段的两个端点。

  已知两直线方程:

\[A_1x+B_1y+C_1=0\\A_2x+B_2y+C_2=0\]

假设交点坐标为$(x_0, y_0)$,由此可得方程组:

\[A_1x_0+B_1y_0+C_1=0\\A_2x_0+B_2y_0+C_2=0\]

解为:

\[x_0=\frac{B_2C_1-B_1C_2}{A_2B_1-A_1B_2}\\y_0=\frac{A_2C_1-A_1C_2}{A_1B_2-A_2B_1}\]