TRI 解题报告
题目大意:
在一个平面上有N(N <= 1000)个点,其中任意三点不共线,求这些点组成的三角形的面积和每和三角形内部含的点数的个数和。
数据范围:
20%的数据 N <= 50, 30% N <= 100, 100% N <= 1000。
算法讨论
算法1:
看到这题还是有部分分的,那么我们首先映入脑袋中的就是O(N^4)的算法,暴力枚举三个点叉积算面积,然后再枚举剩下的点判断是否在当前的三角形内。
如何判断一个点在三角形内部,有个不错的教程:http://www.yalewoo.com/in_triangle_test.html
考场上打这个暴力还是30分妥妥的。
算法2:
O(N^2logn)。
首先对于第一问:
我们考虑,对于一条边来说,边外的点都能和其组成一个三角形,而在枚举边的过程中,可能会对一个三角形多次计算,所以为了避免这种重复计算,我们就要保证一定的顺序,做到不重不漏。于是,对于这样的散点图,我们经常用到的排序方法有两种,第一个是以x为第一关键字,以y为第二关键字进行排序,另一个就是极角排序。(至于不知道什么是极角的,自行百度)。
我们枚举每一个点让其做为一个边的起点,然后以这个点为基准进行极角排序(两种方法,一个是让其它点的坐标都减去这个点的坐标,然后atan2,另一个就是用这个点与其它点的斜率),下面给出这样一个过程。
我们看这样一张图,如果计算S(AOB) + S(AOC) + S(AOD),那么这个面积和就等于 OA叉OB + OA叉OC + OA叉OD
就等于 - xb * ya + xa * yb - xc * ya + xa * yc - xd * ya + xa * yd = -(xb + xc + xd) * ya + xa * (yc + yd + yb),为了保证这个结合是成立的,我们必须保证上面计算的顺序,也要保证都是向左旋,这样叉积才是正的。所以我们对于每一个点为基准,然后枚举那个‘A',就可以得到以每个点为端点的每一个三角形的面积。然后想办法减少计算的重复,就需要极角排序一下。
对于第二问,我们考虑,当我们每选定一个点的时候,那么它最多在C(2,n-1)个三角形中,我们采用补集的思想,当且仅当三个点在这个点同侧的时候,这个点不在三个点围成的三角形中,那么,假设我们当前找的基准点是A,那么已经枚举的那个点是A',我们只要统计AA'一侧的点的数量就可以了,然后组合计数 C(2,...),计算得出答案。同样,为了避免重复, 我们要按照一定的顺序就OK了。
Codes:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll; int n;
struct Point{
double x, y, ji; Point(double _x = , double _y = ): x(_x), y(_y) {}
bool operator < (const Point &a) const{
return ji < a.ji;
}
}p[ * ], T[]; int C(int x, int y){
int ret = ;
for(int i = y; i > y-x; -- i){
ret = ret * i;
}
for(int i = ; i <= x; ++ i)
ret = ret / i;
return ret;
} double Cross(Point a, Point b){
return a.x * b.y - a.y * b.x;
} void Solve(){
ll ans1 = , ans2 = ;
for(int i = ; i <= n; ++ i){
int cnt = ;
for(int j = ; j <= n; ++ j){
if(j != i){
++ cnt;
p[cnt].x = T[j].x - T[i].x; p[cnt].y = T[j].y - T[i].y;
p[cnt].ji = atan2(p[cnt].y, p[cnt].x);
}
}
sort(p + , p + cnt + );
for(int j = ; j <= cnt; ++ j)
p[cnt + j] = p[j];
ans2 += C(, cnt);
for(int j = , k = ; j <= cnt; ++ j){
if(j == k) k ++;
while(Cross(p[j], p[k]) > ) k ++;
Point tp(T[i].x + p[j].x, T[i].y + p[j].y);
ans1 += (long long)Cross(T[i], tp) * (k - j - );
ans2 -= (long long)(k - j - ) * (k - j - ) / ;
}
}
printf("%lf %lf\n", (double) ans1 / / C(, n), (double) ans2 / C(, n));
}
#define ONLINE_JUDGE
int main(){
#ifndef ONLINE_JUDGE
freopen("tri.in", "r", stdin);
freopen("tri.out", "w", stdout);
#endif scanf("%d", &n);
for(int i = ; i <= n; ++ i){
scanf("%lf%lf", &T[i].x, &T[i].y);
} Solve(); #ifndef ONLINE_JUDGE
fclose(stdin); fclose(stdout);
#endif
return ;
}
TRI
TRI 解题报告的更多相关文章
- CH Round #56 - 国庆节欢乐赛解题报告
最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...
- 二模13day1解题报告
二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...
- BZOJ 1051 最受欢迎的牛 解题报告
题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4438 Solved: 2353[S ...
- 习题:codevs 2822 爱在心中 解题报告
这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...
- 习题:codevs 1035 火车停留解题报告
本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...
- 习题: codevs 2492 上帝造题的七分钟2 解题报告
这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...
- 习题:codevs 1519 过路费 解题报告
今天拿了这道题目练练手,感觉自己代码能力又增强了不少: 我的思路跟别人可能不一样. 首先我们很容易就能看出,我们需要的边就是最小生成树算法kruskal算法求出来的边,其余的边都可以删掉,于是就有了这 ...
- NOIP2016提高组解题报告
NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合
- LeetCode 解题报告索引
最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中...... ...
随机推荐
- select p.id, name,ROW_NUMBER() over(PARTITION by name order by p.id) names from person p
select p.id, name,ROW_NUMBER() over(PARTITION by name order by p.id) names from person p
- 查询反模式 - 正视NULL值
一.提出问题 不可避免地,我们都数据库总有一些字段是没有值的.不管是插入一个不完整的行,还是有些列可以合法地拥有一些无效值.SQL 支持一个特殊的空值,就是NULL. 在很多时候,NULL值导致我们的 ...
- ListView中添加ScrollView只显示一两行的问题
将ListView改为继承NoScrollListView package com.example.brtz.widget; import android.content.Context; impor ...
- Php模板引擎Smarty安装和配置
Smarty 是PHP的一个模板引擎,是由Monte Ohrt 和 Andrei Zmievski 使用PHP语言开发的,发展至今已成为一个非常流行的模板引擎,Smarty 提供了一种易于管理和使用的 ...
- hmac_sha1 签名
use URI::Escape qw(uri_unescape); use MIME::Base64; use Digest::HMAC_SHA1; $str=Digest::HMAC_SHA1::h ...
- 【转】Ubuntu10.04上编译Android源码(Build Android source in Ubuntu10.04 Platform)
原文网址:http://blog.csdn.net/chenyafei617/article/details/6570928 一.Introduction 今天我们就来谈谈如何在Ubuntu平台上面编 ...
- mysql5.5 无法创建实例,error 16001
今天想用jdbc做个小程序,结果发现好久不用的mysql不好用了,我装的是社区版(win7)环境下,按理说不可能出问题,找了一堆解决方案都没解决,准备重装的时候想把mysql服务停了,直接在dos输入 ...
- Tomcat部署项目通过—IP地址:端口访问
如题所示,实现效果图如下: 设置如下: (1)修改${tomcat}/config/sever.xml文件虚拟内容目录: <Engine name="Catalina" de ...
- HashMap Java Doc
原文 public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneab ...
- Increasing/ Decreasing Stack
对于此类问题: 对于元素nums[i],找出往左/右走第一个比它小/大的数字 我们常常用递增栈/递减栈实现. 递增栈实现第一个比它小 递减栈实现第一个比它大 Example: 2 1 5 6 2 3 ...