题目传送门
题目大意
“更冷更热”是一个小孩子玩的游戏,游戏玩法是这样的:甲闭上眼睛,让乙在房间里藏一个东西。睁开眼睛后,甲可以猜这个东西在哪里。第一次必须猜(0, 0),以后每猜一个位置,乙根据这个位置和上一次猜的位置哪里离正确位置近做出回答。如果新猜的点比较近,回答“Hotter(更热)”;如果上次猜的点比较近,回答:“Colder(更冷)”。如果二者一样近,回答“Same(相同)”。按顺序给出甲每次猜的位置和乙的回答,依次输出乙每次回答之后,所有可能位置占的总面积。
解题思路
平面内,离两个点一样近的点在这两点所连成的线段的垂直平分线上。
离其中一点更近的点组成中垂线一侧的半平面。
于是这就转化成了半平面交问题。
如何求两点的中垂线呢?首先求出两个点的中点坐标,然后根据两点连线与中垂线垂直求出中垂线。我们规定好方向,如果原向量坐标为(x, y),那么与其垂直的向量坐标就为(-y, x)和(y, -x)。其中前者在原向量的左侧,后者在右侧。
于是根据“更冷”还是“更热”就可以知道我们想要的是哪个半平面,从而确定有向直线(中垂线)的方向。
如果遇到“Same”,明显面积就是0了。这时我们可以特判,也可以直接加两条共线反向的有向直线使得可行域面积为0。
到这里这题的思路就讲完了。这是我很快就想到的,但是。。计算几何题,你懂的。。
我写完后样例死活不过,然后调试半天。找不到问题,但输出中间结果时发现了程序输出了-0,我觉得很奇怪,上网一搜,网上说+0和-0是不同的!!这真是个奇怪的问题:
浮点数的0为0x00000000,浮点数的-0为0x80000000,由于符号位不同导致值不相同。
因此,我们尽量避免在算式中出现-0。
我尽力避免了所有使x或y为-0的语句,一运行发现结果还不对。这时我发现原来是我处理极角序的时候出了点小问题。我一改样例就过了。然后就1A了。
我将语句改回原来的可能有-0的那种,一交还是过了,证明问题并不出在这里。所以,-0的话,尽量避免在算式中出现,但是问题可能并不在此,只是输出-0让人觉得有些奇怪。(以前好像我也遇到过这类情况,不过忘了)
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define N 60
#define Eps 1e-10
using namespace std;
int n, c