模拟CF650,ABC三题,RK90
Codeforces 650 A
思路:首先看式子
\(\sqrt{(x_i-x_j)^2+(y_i-y_j)^2}=|x_i-x_j|+|y_i-y_j|\)
的唯一可行的情况是\(x_i=x_j\)或\(y_i=y_j\)。(因为两边之和大于第三边
所以就知道怎么做了。
- 第一种方法:我们维护三个\(map\),分别存行、列、坐标是\(\dots\)的时候已经有多少个节点。
然后就可以边读边算,读到\((x,y)\)这个坐标的时候把\(ans\)变成
\(row_x+col_y-cnt_{(x,y)}\)就可以了。 - 第二种方法:我们先读完所有的坐标,然后存同一个行、列、坐标各有多少个。
然后枚举每一个不同的行、列、坐标,算出
\(\sum C_{row_x}^2+C_{col_y}^2-C_{cnt_{(x,y)}}^2\)即可。
Codeforces 650 B
思路:二分/two pointers
。
我只会二分了。。。
首先确定我们肯定是向左翻几个,再向右翻几个。(或者相反
那么我们就枚举向左翻到了哪一个(注意复制一遍原数组
然后二分右边到了多少个,用前缀和算一下代价。
然后two pointers
看起来没多少人写???
注意代价要开long long
。
Codeforces 650 C
思路:首先我们把每一行排序。
肯定现在相同的数在“压缩”过后也是相同的。
那就扔到并查集里面当做是一个节点。
然后如果\(x\)小于\(y\)就从\(x\)所在并查集的代表元向\(y\)所在的代表元连边。
这说明\(y\)的压缩后的值肯定大于\(x\)压缩后的值。
但这样边数是\(O(n^2)\)的。
注意到我们这样连边等价于我们只连同一行内大小连续的数的边。
这样就很可做了。直接一把\(bfs\)标记在\(dag\)上下推即可。
还可以直接拓扑排序后一个小小的\(dp\)。
其实没有必要正经地“拓扑排序”,只需要把所有的格子按照数的大小排就可以了。
因为从小的到大的连边啊。。。
那样就可以一个main
函数干到底了(雾
原文地址:https://www.cnblogs.com/denverjin/p/10674383.html
时间: 2024-10-05 21:22:38