UVa 1606 Amphiphilic Carbon Molecules 题解

Posted alrond

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 1606 Amphiphilic Carbon Molecules 题解相关的知识,希望对你有一定的参考价值。

难度:β

建议用时:40 min

实际用时:1 h

题目:??

代码:??

 

这题我看了刘汝佳大神的代码,在上面改了几个变量的名称,方便理解。

 

这是一道简单的几何题(不是真正的集合题,更可以说是一个坐标题),所以长话短说了。

 

题目告诉我们有一些随机分布的点,要我们用一个隔板把平面分开,然后往两边分别倒入水和丙酮来溶解掉这些点。

然而这些点有的只能溶解在水里,有的只能溶解到丙酮里。

任务是找到最大的溶解的点的数量。

 

这题建模就是按照刘汝佳大神的方法,一个隔板分开平面,要使左侧黑点数加右侧白点数的和最大。找到最大值。

 

具体的算法就不讨论了,书上有。

 

这里说一下大神的代码里的细节。

 

首先弄一个结构体,存点的相对坐标与相对角。

相对谁呢?相对枚举的原点。

for (int pivot = 0; pivot < n; pivot++)

以这个枚举的点为原点建立坐标系,表示每个点的坐标和与 x 轴正半轴的夹角。

for (int p = 0; p < n; p++) {
    if (p == pivot) continue;
    rlt_pos[tot].x = abs_pos[p].x - abs_pos[pivot].x;
    rlt_pos[tot].y = abs_pos[p].y - abs_pos[pivot].y;
    if (color[p] == 1) { rlt_pos[tot].x = -rlt_pos[tot].x; rlt_pos[tot].y = - rlt_pos[tot].y; }
    rlt_pos[tot].rad = atan2(rlt_pos[tot].y, rlt_pos[tot].x);
    tot++;
}

这里我把大神的代码里面的一些变量名称改了一下,便于我自己理解。

注意到大神有一个方便的做法。他把右侧的黑点当作左侧的白点,然后下面只统计左侧的点(不管颜色)有几个(而不是先统计左侧的白点又统计右侧的黑点)。这样统计时更快更便捷。

然后把每个点按相对夹角排序,这样可以保证一个一个扫描。

 

接下来就是重点了。扫描。

这个扫描的步骤我看了半天才明白。

其大致想法是:对每一个分割线,统计左边点的个数,然后让扫描到的点标号不变,改变分割点,继续从上次扫描的地方开始扫描,计数。

这样的好处是,不用每次改变分割线后重新从分割线开始扫描。前面的复杂度是 n^2,优化后是 n。

1 int L = 0, R = 0, cnt = 2; // 初始时记扫描点为 L,分割点为 R。
2 while (R < tot) {
3     if (L == R) { L = (L+1)%tot; cnt++; } // 如果扫描点与分割点重合,计数加一
4     while (L != R && left(rlt_pos[L], rlt_pos[R])) { L = (L+1)%tot; cnt++; } // 扫描
5     cnt--; // 减掉上次的分割点
6     R++; // 分割点改变
7     ans = max(ans, cnt);
8 }

这里比较难想的是第 3 行和第 5 行。

不难发现,第 3 行只在第一次扫描时执行。因为之后扫描点与分割点不可能重合了,这是因为我们要求扫描点必须要在分割点左边。

即使在某次扫描时扫描点刚好转到了分割点(然后退出第 4 行),然而分割点每次加 1,这样扫描点依然追不上分割点。

 

第 5 行。这里转完以后统计时要减 1,减的是上次的分割点。然而对于第一次扫描是不存在“上一个”分割点的,所以 cnt 的初始值设为 2。cnt 代表当前确定的点数。cnt = 1 是原点。

 

大神的代码让我看的花方。

 

2018-02-03

以上是关于UVa 1606 Amphiphilic Carbon Molecules 题解的主要内容,如果未能解决你的问题,请参考以下文章

UVa1606 Amphiphilic Carbon Molecules (扫描法+极角排序)

UVA - 1606 Amphiphilic Carbon Molecules (计算几何,扫描法)

UVA - 1606 Amphiphilic Carbon Molecules 极角扫描法

UVa 1606 两亲性分子

POJ1598 ZOJ1315 HDU1606 UVA409 UVALive5493 Excuses, Excuses!文本

qt多次调用函数显示多张图片