How Many Triangles (极角排序 + 尺取法)
题意:二维平面与有很多个点,然后求构成锐角三角形的个数。
思路:对于每一个三角形我们知道存在至少2个锐角,只要有一个钝角就不行了,所以我们的想法就是枚举所有夹角的状态,然后得知情况,确定用总个数减去-成线或者成钝角的数量/2(除以2是因为计算过程中重复了)。那么应该如何枚举?我们枚举夹角的顶点然后就出其他点的极角,排序,然后尺取法左端点表示与当前点为锐角的个数,右端点表示锐角+钝角,过程中相减可以得到锐角数量。
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
const int maxn = + ;
struct P{
ll x, y;
P() {}
P(ll x, ll y): x(x), y(y) {}
P operator + (P p) {
return P(x + p.x, y + p.y);
}
void read() {
scanf("%lld%lld", &x, &y);
}
P operator - (P p) {
return P(x - p.x, y - p.y);
}
ll dot(P p) {//点积
return x * p.x + y * p.y;
}
ll det(P p) {//叉积
return x * p.y - y * p.x;
}
bool operator < (const P &p) const{
if(y * p.y <= ) {
if(y > || p.y > ) return y < p.y;
if(y == && p.y == )return x < p.x;
}
return x * p.y - y * p.x > ;
}
}p[maxn], q[maxn << ]; int main(){
int n;while(~scanf("%d", &n)) {
ll ans = 1ll * n * (n - ) * (n - ) / ;
ll line = ;
for(int i = ; i < n; i ++) p[i].read();
for(int i = ; i < n; i ++) {
int tot = ;
for(int j = ; j < n; j ++)
if(i != j) q[tot ++] = p[j] - p[i];
ll subtrat = ;
sort(q, q + tot);
for(int j = ; j < tot; j ++) q[j + tot] = q[j];
for(int j = ; j < tot; j ++) {
if(q[j - ].det(q[j]) == && q[j - ].dot(q[j]) > ) subtrat ++;
else subtrat = ;
line += subtrat;
}
int l = , r = ;
for(int j = ; j < tot; j ++) {
while(l <= j || (l < j + tot && q[l].det(q[j]) < && q[j].dot(q[l]) > )) l ++;
while(r <= j || (r < j + tot && q[r].det(q[j]) < )) r ++;
ans -= r - l;
}
}
printf("%lld\n",ans - line/);
}
return ;
}
How Many Triangles (极角排序 + 尺取法)的更多相关文章
- [CF1025F]Disjoint Triangles[极角排序+组合计数]
题意 平面上有 \(n\) 个点,选出六个点构成两个三角形,问有多少种构造方式使得两个三角形没有交集. \(n\leq 2000\) 分析 枚举连接两个三角形的两个顶点,同时能够将两个三角形划分在直线 ...
- hdu-5784 How Many Triangles(计算几何+极角排序)
题目链接: How Many Triangles Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- 【计算几何】【极角排序】【二分】Petrozavodsk Summer Training Camp 2016 Day 6: Warsaw U Contest, XVI Open Cup Onsite, Sunday, August 28, 2016 Problem J. Triangles
平面上给你n(不超过2000)个点,问你能构成多少个面积在[A,B]之间的Rt三角形. 枚举每个点作为直角顶点,对其他点极角排序,同方向的按长度排序,然后依次枚举每个向量,与其对应的另一条直角边是单调 ...
- nyoj133_子序列_离散化_尺取法
子序列 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次. 如2 8 ...
- 51nod-1686 第K大区间(二分+尺取法)
题目链接: 第K大区间 基准时间限制:1 秒 空间限制:131072 KB 定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. Input 第一行两个数 ...
- POJ_2566_Bound_Found_(尺取法+前缀和)
描述 http://poj.org/problem?id=2566 给出一个整数序列,并给出非负整数t,求数列中连续区间和的绝对值最接近k的区间左右端点以及这个区间和的绝对值. Bound Found ...
- POJ2566-Bound Found (尺取法)
POJ2566-Bound Found 题目大意:给出一段长度为n的数列,数列中的元素有正有负,求一段连续的区间,使得该区间的和的绝对值最接近给定的值 尺取法一般适用于对一段连续的区间的和进行处理的情 ...
- 【尺取法】Jurisdiction Disenchantment
[尺取法]Jurisdiction Disenchantment PROBLEM 时间限制: 1 Sec 内存限制: 128 MB 题目描述 The Super League of Paragons ...
- poj 2566"Bound Found"(尺取法)
传送门 参考资料: [1]:http://www.voidcn.com/article/p-huucvank-dv.html 题意: 题意就是找一个连续的子区间,使它的和的绝对值最接近target. ...
随机推荐
- JAVA课程课后作业03之动手动脑
一.构造函数 问题一: 错误代码如图: 错误原因:从图片中的编译报错的地方来看,程序是在给新的对象分配空间是出现了问题,因而我们往下观察Foo类,Foo类的构造方法是有一个参数的有参方法,而前面构造新 ...
- spring-boot(三) HowTo
Spring Boot How To 1. 简介 本章节将回答一些常见的"我该怎么做"类型的问题,这些问题在我们使用spring Boot时经常遇到.这绝不是一个详尽的列表,但它覆 ...
- mui APP与服务器之间的交互原理
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- Python学习之旅(三十六)
Python基础知识(35):电子邮件(Ⅱ) 收取邮件就是编写一个MUA作为客户端,从MDA把邮件获取到用户的电脑或者手机上 收取邮件最常用的协议是POP协议,目前版本号是3,俗称POP3 Pytho ...
- javascript的数组之from()
Array.from()方法从一个类似数组或可迭代对象中创建一个新的数组实例. const arr = [1, 2, 3]; Array.from(arr); //[1, 2, 3] Array.fr ...
- Grunt Bower构建前端
Grunt + Bower—前端构建利器 目前比较流行的WEB开发的趋势是前后端分离.前端采用重量级的Javascript框架,比如Angular,Ember等,后端采用restful API的W ...
- python全栈开发 * 18 面向对象知识点汇总 * 180530
18 面向对象初识1class person: level="高级动物" mind="有思想" def __init__(self,name,age,gent, ...
- JavaScript基础知识(数组的方法)
数组的方法(15个) 对象数据类型: 数组成员有一个与之对应的索引 length : 代表数组成员的个数: 操作改变数组一些方法:这些数组的方法都是内置的: // 1. 方法作用: // 2. 方法的 ...
- 360自带--JS开发工具箱
360自带–JS开发工具箱 360自带–JS开发工具箱 360自带–JS开发工具箱
- PAT甲级1135 Is It A Red-Black Tree?【dfs】
题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805346063728640 题意: 给定一棵二叉搜索树的先序遍历结 ...