hihoCoder 1225 向日葵(凸包)

题目链接:hihoCoder 1225 向日葵

枚举每条线段称为凸包边界的概率。注意一对点中有1个在线段左边*0.5,0个在线段左边*0,2个都在线段左边*1。最后答案要除4,因为枚举的两个点也要算概率。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <complex>
#include <algorithm>

using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const double pi = 4 * atan(1);
const double eps = 1e-10;

inline int dcmp (double x) { if (fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; }
inline double getDistance (double x, double y) { return sqrt(x * x + y * y); }
inline double torad(double deg) { return deg / 180 * pi; }

struct Point {
	int id;
	double x, y, ang;
	Point (double x = 0, double y = 0, double ang = 0, int id = 0): x(x), y(y), ang(ang), id(id) {}
	void read () { scanf("%lf%lf", &x, &y); }

	bool operator < (const Point& u) const { return dcmp(x - u.x) < 0 || (dcmp(x-u.x)==0 && dcmp(y-u.y) < 0); }
	bool operator > (const Point& u) const { return u < *this; }
	bool operator == (const Point& u) const { return dcmp(x - u.x) == 0 && dcmp(y - u.y) == 0; }
	bool operator != (const Point& u) const { return !(*this == u); }
	bool operator <= (const Point& u) const { return *this < u || *this == u; }
	bool operator >= (const Point& u) const { return *this > u || *this == u; }
	Point operator + (const Point& u) { return Point(x + u.x, y + u.y); }
	Point operator - (const Point& u) { return Point(x - u.x, y - u.y); }
	Point operator * (const double u) { return Point(x * u, y * u); }
	Point operator / (const double u) { return Point(x / u, y / u); }
	double operator * (const Point& u) { return x*u.y - y*u.x; }
};
typedef Point Vector;

const int maxn = 1005;

int N, V[maxn], C1, C2;
Point A[maxn], B[maxn], T[maxn * 4];

double getCross (Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
double getArea (Point a, Point b, Point c) { return getCross(b - a, c - a) / 2; }
inline int cmp(const Point& a, const Point& b) { return a.ang < b.ang; }

void add (int x) {
	V[x]++;
	if (V[x] == 1)
		C1++;
	else
		C1--, C2++;
}

void del (int x) {
	V[x]--;
	if (V[x] == 0)
		C1--;
	else
		C2--, C1++;
}

double solve(Point* P) {
	double ans = 0;
	for (int i = 0; i < N; i++) {
		int sz = 0;
		for (int j = 0; j < N; j++) if (i != j) {
			T[sz++] = Point(A[j].x, A[j].y, atan2(A[j].y-P[i].y, A[j].x-P[i].x), j);
			T[sz++] = Point(B[j].x, B[j].y, atan2(B[j].y-P[i].y, B[j].x-P[i].x), j);
		}
		for (int j = 0; j < sz; j++) {
			T[sz + j] = T[j];
			T[sz + j].ang += 2 * pi;
		}
		sort(T, T + 2 * sz, cmp);

		int r = 0;
		C1 = C2 = 0;
		memset(V, 0, sizeof(V));

		add(T[r].id);
		for (int j = 0; j < sz; j++) {
			del(T[j].id);
			while (T[r+1].ang - T[j].ang < pi) add(T[++r].id);
			//while (C1 + 2 * C2 != r - j);
			int c = C1 - V[T[j].id];
			if (c + C2 !=  N - 2) continue;
			ans += getArea(Point(0, 0), P[i], T[j]) * pow(0.5, c);
		}
	}
	return ans;
}

int main () {
	while (scanf("%d", &N) == 1) {
		for (int i = 0; i < N; i++) A[i].read(), B[i].read();

		double ans = solve(A) + solve(B);
		printf("%lf\n", ans / 4);
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-29 19:09:54

hihoCoder 1225 向日葵(凸包)的相关文章

hihoCoder挑战赛14 A,B,C题解

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 题目1 : 不等式 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定n个关于X的不等式,问最多有多少个成立. 每个不等式为如下的形式之一: X < C X <= C X = C X > C X >= C 输入 第一行一个整数n. 以下n行,每行一个不等式. 数据范围: 1<=N<=50,0<=C<=1000

POJ3528 HDU3662 三维凸包模板

POJ3528 HDU3662 第一道题 给定若干点 求凸包的表面积,第二题 给定若干点就凸包的面数. 简单说一下三维凸包的求法,首先对于4个点假设不共面,确定了唯一四面体,对于一个新的点,若它不在四面体内,为了让它进入凸包, 则对于所有凸包上的边,若边的一面是该点可以看到的而另一面看不到,则该点与该边构成的面要加入凸包. 模板代码非常清晰, #include<stdio.h> #include<algorithm> #include<string.h> #includ

1225 八数码难题

1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765

关于2016.12.12——T1的反思:凸包的意义与应用

2016.12.12 T1 给n个圆,保证圆圆相离,求将圆围起来的最小周长.n<=100 就像上图.考场上,我就想用切线的角度来做凸包.以圆心x,y排序,像点凸包一样,不过用两圆之间的下切线角度来判断. 这就是下切线(我自己瞎编的名字): 好像是对的啊: 然后我就保证必AC的希望,用这种写法交了,然后就只得了N=2的暴力分... 自以为是正解,却落得如此下场... 为什么?这样不对吗?借用学长的力量,果然被Hack掉了: 这种情况,圆心排序后,检测的顺序并不是圆上的切点的顺序,自然就会挂. 蓝瘦

[hihoCoder#1381]Little Y&#39;s Tree

[hihoCoder#1381]Little Y's Tree 试题描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每次小J会删掉这个树中的k条边,这棵树被分成k+1个连通块.小J想知道每个连通块中最远点对距离的和. 这里的询问是互相独立的,即每次都是在小Y的原树上进行操作. 输入 第一行一个整数n,接下来n-1行每行三个整数u,v,w,其中第i行表示第i条边边权为wi,连接了ui,vi两点. 接下来一行一个整数q,表示有q组询问. 对于每组询问,第一行一个正整数k,接下来一

poj 1113 凸包周长

Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 33888   Accepted: 11544 Description Once upon a time there was a greedy King who ordered his chief Architect to build a wall around the King's castle. The King was so greedy, that he w

hihoCoder 1175:拓扑排序二

题目链接: http://hihocoder.com/problemset/problem/1175 题目难度:一星级(简单题) 今天闲来无事,决定刷一道水题.结果发现这道水题居然把我卡了将近一个钟头. 最后终于调通了.总结起来,原因只有一个:不够仔细. 思路不用细说了,就是拓扑排序的简单应用.然而,一些不起眼的细节才是让你掉坑里的真正原因. 猜猜哪儿可能出bug? // A simple problem, but you can't be too careful with it. #inclu

UVA 11800 Determine the Shape --凸包第一题

题意: 给四个点,判断四边形的形状.可能是正方形,矩形,菱形,平行四边形,梯形或普通四边形. 解法: 开始还在纠结怎么将四个点按序排好,如果直接处理的话,有点麻烦,原来凸包就可搞,直接求个凸包,然后点就自动按逆时针排好了,然后就判断就可以了,判断依据题目下面有,主要是用到点积和叉积,判断垂直用点积,判断平行用叉积. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cstd

POJ 3348 最直接的凸包问题

题目大意: 给定一堆树的点,找到能组合成的最大面积,一个物体占50面积,求最多放多少物体 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 const double eps = 1e-10; 7 const int N = 10005; 8 double myabs(double x) 9