bzoj-1132 Tro

题意:

给出n个点,求这n个点组成的所有三角形的面积和;

n<=3000;

题解:

这道题O(n^3)枚举三角形时间复杂度是无法承受的;

所以考虑枚举一条边,多个三角形一起来计算,复杂度在O(n^2)的级别;

求三角形面积可以底乘高的面积公式,也可以上叉积;

如果采用底乘高的方法,求出所有的点到直线的距离之和,也是可以O(1)得到当前的解的;

但是求距离之和这一步必然是O(n)的,也难以转移到下一个底上去;

而叉积的方法则是化简叉积的式子,可以把点的坐标提出来,加和一起运算;

但是叉积求得的是有向面积,这东西卡了我半天;

实际上实现是这样的:

枚举第一个点,取第一个点右上方的点集,将点集按与第一个点的斜率大小排序,然后枚举第二个点求解;

这样每个面积只求了一遍,而且因为斜率有序,所以所有三角形都是正的面积了;

因为排了序,所以时间复杂度O(n^2 logn);

(我居然因为保留两位小数WA了一晚上!!)

代码:

#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 3100
using namespace std;
typedef long long ll;
struct Point
{
	ll x,y;
	double slope;
	friend bool operator <(Point a,Point b)
	{
		if(a.x==b.x)
		return a.y<b.y;
		return a.x<b.x;
	}
	friend Point operator -(Point a,Point b)
	{
		return (Point){a.x-b.x,a.y-b.y};
	}
	friend int operator *(Point a,Point b)
	{
		return a.x*b.y-a.y*b.x;
	}
}a[N],t[N],O;
bool cmp(Point a,Point b)
{
	return a.slope>b.slope;
}
int main()
{
	int n,m,i,j,k;
	ll ans,sx,sy,tx,ty;
	scanf("%d",&n);
	for(i=1,sx=sy=0;i<=n;i++)
	{
		scanf("%d%d",&a[i].x,&a[i].y);
		sx+=a[i].x,sy+=a[i].y;
	}
	sort(a+1,a+1+n);
	for(i=1,ans=0;i<=n;i++)
	{
		sx-=a[i].x,sy-=a[i].y;
		tx=sx,ty=sy;
		O=a[i];
		memcpy(t+i+1,a+i+1,sizeof(Point)*(n-i));
		for(j=i+1;j<=n;j++)
		{
			if(t[j].x==O.x)
				t[j].slope=1e10;
			else
				t[j].slope=(double)(t[j].y-O.y)/(t[j].x-O.x);
		}
		sort(t+i+1,t+n+1,cmp);
		for(j=i+1;j<n;j++)
		{
			Point v=t[j]-a[i];
			tx-=t[j].x,ty-=t[j].y;
			ans+=tx*v.y-ty*v.x+(n-j)*(a[i].y*v.x-a[i].x*v.y);
		}
	}
	printf("%lld.%d",ans>>1,ans&1?5:0);
	return 0;
}
时间: 2024-10-08 04:11:47

bzoj-1132 Tro的相关文章

[POI 2008][BZOJ 1132]Tro

这题我真是无能为力了 这题的做法还是挺简单的 枚举左下角的点做为原点,把其余点按极角排序    PS.是作为原点,如枚举到 k 时,对于所有 p[i] (包括p[k]) p[i]-=p[k] (此处为向量减法) 排序后满足 i<j 的两个向量 p[i] 和 p[j] 的叉积都是正数了 ΣΣp[i]×p[j] = ΣΣ(p[i].x*p[j].y-p[i].y*p[j].x) = Σ(p[i].x*Σp[j].y)-Σ(p[i].y*Σp[j].x) 计算叉积和的复杂度就从 O(n2) 降为了 O

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 于是

BZOJ 1132 POI 2008 Tro 计算几何

题目大意:给出平面上的一些点,问这些点中的任意三个点组成的三角形的面积和是多少. 思路:看数据范围只算法系列.由于每个三角形有三个顶点,因此暴力的话应该是O(n^3)的时间复杂度,很明显超时了,但是我们只需要将它优化到O(n^2logn)就可以解决了. 好吧,剩下的随便猜一猜,比如O(n^2)的枚举,然后剩下的logn什么也干不了... 再比如O(n)的枚举,然后剩下O(nlogn)排序... 好像有戏啊.. 枚举每一个点,计算以这个点为坐标原点,在第一象限的所有点与原点组成的三角形的面积和.计

bzoj 1132 几何

思路:我刚开始算三角形的方法是原点叉积三条边,然后计算每条边向量积的贡献,但是对于同一条线上的点 有时候没有办法抵消掉..... 看网上的思路是对于一个三角形的面积通过两条边的叉积获得,然后枚举一个点,排序去掉公式的绝对值,记录 后缀和进行计算... 看的这篇博客.. https://www.cnblogs.com/GXZlegend/p/7509699.html #include<bits/stdc++.h> #define LL long long #define fi first #de

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

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max

bzoj 3309 DZY Loves Math - 莫比乌斯反演 - 线性筛

对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0. 给定正整数a,b,求sigma(sigma(f(gcd(i,j)))) (i=1..a, j=1..b). Input 第一行一个数T,表示询问数. 接下来T行,每行两个数a,b,表示一个询问. Output 对于每一个询问,输出一行一个非负整数作为回答. Sample Input 4 7558588 9653114 6514903 445

【BZOJ】[HNOI2009]有趣的数列

[算法]Catalan数 [题解] 学了卡特兰数就会啦>_<! 因为奇偶各自递增,所以确定了奇偶各自的数字后排列唯一. 那么就是给2n个数分奇偶了,是不是有点像入栈出栈序呢. 将做偶数标为-1,做奇数标为+1,显然当偶数多于奇数时不合法,因为它压不住后面的奇数. 然后其实这种题目,打表就可知啦--QAQ 然后问题就是求1/(n+1)*C(2n,n)%p了,p不一定是素数. 参考bzoj礼物的解法. 看到网上清一色的素数筛+分解质因数解法,不解了好久,感觉写了假的礼物-- 后来觉得礼物的做法才比