【BZOJ1132】[POI2008]Tro 几何

【BZOJ1132】[POI2008]Tro

Description

平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和 N<=3000

Input

第一行给出数字N,N在[3,3000] 下面N行给出N个点的坐标,其值在[0,10000]

Output

保留一位小数,误差不超过0.1

Sample Input

5
0 0
1 2
0 2
1 0
1 1

Sample Output

7.0

题解:我们将所有点按x排序,枚举最左面的点。设当前点为i,我们想计算右面所有点对与其形成三角形的面积和。回忆起叉积的式子了吗?我们其实就是想计算$\sum\limits_{j>i}\sum\limits_{k>j}|aj*bk-ak*bj|$,其中aj=xj-xi,以此类推。

但是有绝对值怎么办?按斜率排序去绝对值即可。然后呢?前缀和优化一下就行了。

由于卡精,本题坐标要用int,斜率用double,答案用long long,并且输出的时候要当成整数输出!

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=3010;
typedef long long ll;
int n;
struct point
{
	int x,y;
	double a;
	point() {}
	point(int _1,int _2) {x=_1,y=_2,a=!x?1e10:(double)y/x;}
}p[maxn],q[maxn];
ll ans,sx,sy;
bool cmpx(point a,point b)
{
	return (a.x==b.x)?(a.y<b.y):(a.x<b.x);
}
bool cmpa(point a,point b)
{
	return a.a<b.a;
}
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
int main()
{
	n=rd();
	int i,j;
	for(i=1;i<=n;i++)	p[i].x=rd(),p[i].y=rd();
	sort(p+1,p+n+1,cmpx);
	for(i=1;i<=n-2;i++)
	{
		for(j=i+1;j<=n;j++)	q[j-i]=point(p[j].x-p[i].x,p[j].y-p[i].y);
		sort(q+1,q+n-i+1,cmpa);
		for(sx=sy=0,j=n-i;j;j--)	ans+=q[j].x*sy-sx*q[j].y,sy+=q[j].y,sx+=q[j].x;
	}
	printf("%lld.%d\n",ans>>1,(ans&1)?5:0);
	return 0;
}
时间: 2024-11-05 19:29:02

【BZOJ1132】[POI2008]Tro 几何的相关文章

BZOJ1132: [POI2008]Tro

1132: [POI2008]Tro Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 815  Solved: 211[Submit][Status] Description 平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和 N<=3000 Input 第一行给出数字N,N在[3,3000] 下面N行给出N个点的坐标,其值在[0,10000] Output 保留一位小数,误差不超过0.1 Sample Input 5 0 0 1 2 0

【bzoj1132】[POI2008]Tro 计算几何

题目描述 平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和 N<=3000 输入 第一行给出数字N,N在[3,3000] 下面N行给出N个点的坐标,其值在[0,10000] 输出 保留一位小数,误差不超过0.1 样例输入 5 0 0 1 2 0 2 1 0 1 1 样例输出 7.0 题解 计算几何 考虑到所求的所有三角形的面积之和为$\sum\limits_{i<j<k}|(y_j-y_i)*(x_k-x_i)-(y_k-y_i)*(x_j-x_i)|$,这样直接计算的时间复杂

BZOJ 1132 [POI2008]Tro(极角排序)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1132 [题目大意] 平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和(N<=3000) [题解] 我们发现直接枚举三个点计算会造成很大部分的叉积重复被计算, 因此我们枚举i,计算pj和pi点差的后缀和,我们发现对于固定边ij, 其与后面的枚举量相关贡献就为pj-pi和点差后缀和的叉积. 因此我们针对每个i进行后面数据的极角排序,O(n)计算与i相关的所有答案贡献. [代码]

bzoj 1132 POI2008 Tro

大水题=_=,可我想复杂了…… 很裸的暴力,就是加了个小优化…… 叉积求面积 :abs(xi*yj - yi*xj) 所以去掉绝对值,把 xi 和 xj 提出来就可以求和了 去绝对值加个极角排序,每次把最左边的点当成原点,然后剩下的排序,接着枚举第二个点,求叉积之和…… 坐标都是整数,用long long,最后再除2 上代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <ios

BZOJ 1132 POI2008 Tro 计算几何

题目大意:给定平面上的一些点,求这些点能组成的所有三角形的面积之和 首先我们枚举每一个点 以这个点为原点建立平面直角坐标系 然后将第一.四象限和x.y轴正半轴上的点按照斜率排序 枚举第二个和第三个点 这样做是O(n^3)的 肯定超时 但是我们发现了什么? 对于每个点k 它对答案的贡献为: (x1*yk-y1*xk)+(x2*yk-y2*xk)+...+(x_(k-1)*yk-y_(k-1)*xk) =(x1+x2+...+x_(k-1))*yk-(y1+y2+...+y_(k-1))*xk 于是

2016.08.06计算几何总结测试day1

T1 bzoj1132[POI2008]TRO 还是太弱了....测试时看到这题直接懵逼,极角排序什么的根本想不起来,只会n^3暴力怎么破......不过竟然有84.....QAQ 正解是n^2logn的,首先为了避免算重,以点的x坐标为第一关键字和y坐标为第二关键字排好序,然后O(n)枚举当前点计算以当前点为三角形的一个顶点的三角形面积之和. 显然不能n^2枚举,于是想到nlogn极角排序,以当前点为原点建一个平面直角坐标系,加一个前缀和将计算优化到O(n),于是就是n^2logn的了 至于怎

【BZOJ1132】【POI2008】Tro 计算几何 叉积求面积

链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/46605807"); } 题解: 首先暴力是 O(n3) 求每个三角形面积! 可是三角形面积怎么求?一般我们都是用叉积--等等?那一个叉积不是被算了很多遍? 好了,正解出来了,先有序地把点排排序保证不重,然后算一下每个

bzoj-1132 Tro

题意: 给出n个点,求这n个点组成的所有三角形的面积和: n<=3000: 题解: 这道题O(n^3)枚举三角形时间复杂度是无法承受的: 所以考虑枚举一条边,多个三角形一起来计算,复杂度在O(n^2)的级别: 求三角形面积可以底乘高的面积公式,也可以上叉积: 如果采用底乘高的方法,求出所有的点到直线的距离之和,也是可以O(1)得到当前的解的: 但是求距离之和这一步必然是O(n)的,也难以转移到下一个底上去: 而叉积的方法则是化简叉积的式子,可以把点的坐标提出来,加和一起运算: 但是叉积求得的是有

POI2008 题解

POI2008 完结(′?_?`)撒花! 海报PLA 单调栈裸题! 激光发射器SZK 光路可逆? 然后证一下发射器与接收器两两对应? 砖块Klo 区间中值! 可用树状数组水过... 将高度 \( h \) 的值域作为树状数组维护的序列,维护一下前缀数量与前缀和即可. BLO 求割点裸题! Sta so easy 的树上DP! CLO 蜜汁构造... Tro 草稿题... 把差积分开算,求和 枪战Maf 有向仙人掌? naive! 贪心构造即可(<--口胡的) 正解还要分好多种情况? 账本BBB