【计算几何+极角排序+爆ll】E. Convex
https://www.bnuoj.com/v3/contest_show.php?cid=9147#problem/E
【题意】
给定n个点的坐标,可以选择其中的四个点构造凸四边形,问最多能构造多少个凸四边形?
【思路】
凸四边形的个数等于C(n,4)-凹四边形的个数。
凹四边形的特点是有一个顶点被另外三个顶点围成的三角形包了起来。
所以现在的问题就是找凹四边形。
我们可以枚举每个点,作为被三角形包围的中心点o。怎么找这样包围中心点的三角形?
这样的三角形一定是在存在一条经过中心点的直线,三角形的三个顶点在直线的同一侧。
那么枚举三角形的一个顶点x,另两个顶点一定在o和x的连线ox的上半平面内。而且这样做类似与尺取,只需O(n)的复杂度。
最后注意的一点是:
printf("%I64d\n",-3LL*n*(n-1)*(n-2)*(n-3)/24+cnt);
printf("%I64d\n",n*(n-1)*(n-2)*(n-3)/24LL-(n*(n-1)*(n-2)*(n-3)/6LL-cnt));
的区别。
前者在前面成了3LL,所以计算连乘的时候是把int转化为ll,不会爆
后者n*(n-1)*(n-2)*(n-3)在计算的过程中已经爆了。
解决办法有两种:
在前面乘以1LL;n变成ll
【Accelerate】
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm> using namespace std;
typedef long long ll;
const int maxn=;
int n;
ll xx[maxn];
ll yy[maxn];
int cur;
double dis(ll x1,ll y1,ll x2,ll y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
struct Point
{
ll x;
ll y;
double dis;
double alf;
Point(){}
Point(ll _x,ll _y):x(_x),y(_y){}
Point operator -(const Point &t) const
{
return Point(x-t.x,y-t.y);
}
ll operator ^(const Point &t)const
{
return (x*t.y)-(y*t.x);
}
double alfa()
{
if(y>yy[cur])return acos((x-xx[cur])/dis);
return -acos((x-xx[cur])/dis);
}
}p[maxn]; bool cmp(Point a,Point b)
{
if(b.x==xx[cur]&&b.y==yy[cur])
{
return true;
}
if(a.x==xx[cur]&&a.y==yy[cur])
{
return false;
}
return a.alf<b.alf;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
cin>>xx[i]>>yy[i];
p[i]=Point(xx[i],yy[i]);
}
ll cnt=;
for(cur=;cur<n;cur++)
{ int l=;
Point o(xx[cur],yy[cur]);
for(int i=;i<n;i++){p[i].dis=dis(p[i].x,p[i].y,xx[cur],yy[cur]);p[i].alf=p[i].alfa();}
sort(p,p+n,cmp);
for(int i=;i<n-;i++)
{
while(((p[i]-o)^(p[l]-o))>)
{
l=(l+)%(n-);
}
int len=(l-i-+n-)%(n-);
cnt+=len*(len-)/;
}
}
// ll ans=n*(n-1)*(n-2)*(n-3)/24LL-(n*(n-1)*(n-2)*(n-3)/6LL-cnt);//注意,这样会爆
// printf("%I64d\n",-3LL*n*(n-1)*(n-2)*(n-3)/24+cnt);//前面乘以3LL,不会爆
printf("%I64d\n",1LL*n*(n-)*(n-)*(n-)/24LL-(1LL*n*(n-)*(n-)*(n-)/6LL-cnt));
}
return ;
}
【知识点】
判断是不是在一个半平面内用到了叉积的性质:
叉积的一个非常重要的性质是通过它的符号判断两向量相互之间的顺逆时针关系:设向量P=(x1,y1),Q=(x2,y2)
如果P*Q>0则P在Q的顺时针方向;
如果P*Q=0则P与Q共线,可能同向,与可能反向;
如果P*Q<0则P在Q的逆时针方向。
【计算几何+极角排序+爆ll】E. Convex的更多相关文章
- bzoj 5099 [POI2018]Pionek 计算几何 极角排序
[POI2018]Pionek Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 269 Solved: 80[Submit][Status][Disc ...
- hdu-5784 How Many Triangles(计算几何+极角排序)
题目链接: How Many Triangles Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- hrbustoj 1305:多边形(计算几何,极角排序练习)
多边形 Time Limit: 1000 MS Memory Limit: 65536 K Total Submit: 113(42 users) Total Accepted: 51(3 ...
- poj 1696:Space Ant(计算几何,凸包变种,极角排序)
Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2876 Accepted: 1839 Descrip ...
- Gym 101986D Making Perimeter of the Convex Hull Shortest(凸包+极角排序)
首先肯定是构造一个完整的凸包包括所有的点,那么要使得刚好有两个点在外面,满足这个条件的只有三种情况. 1.两个在凸包上但是不连续的两个点. 2.两个在凸包上但是连续的两个点. 3.一个在凸包上,还有一 ...
- 【计算几何】【极角排序】【二分】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三角形. 枚举每个点作为直角顶点,对其他点极角排序,同方向的按长度排序,然后依次枚举每个向量,与其对应的另一条直角边是单调 ...
- 【计算几何】【凸包】【极角排序】【二分】Gym - 101128J - Saint John Festival
平面上n个红点,m个黑点,问你多少个黑点至少在一个红三角形内. 对红点求凸包后,转化为询问有多少个黑点在凸包内. 点在凸多边形内部判定,选定一个凸包上的点作原点,对凸包三角剖分,将其他的点极角排序之后 ...
- LightOJ 1285 - Drawing Simple Polygon (几何,极角排序)
1285 - Drawing Simple Polygon PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: ...
- HDU 5738 Eureka(极角排序)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5738 [题目大意] 给出平面中一些点,在同一直线的点可以划分为一个集合,问可以组成多少包含元素不少 ...
随机推荐
- 如何移除EditText自动焦点
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_cont ...
- Nuget 自定义配置(官网)
<?xml version="1.0" encoding="utf-8"?> <configuration> <config> ...
- 关于tomcat一些简介
window下,在tomcat的bin目录下,用cmd输入startup.bat 即可启动tomcat 成功启动Tomcat后,通过访问http://localhost:8080/便可以使用Tomca ...
- GUI初步和frame&panel
java的话这个GUI其实不是什么重点,但我们也要学习,重点是学习这种图形编程的思路. java里面对于图形的一些类都封装在了AWT和它的一些子包里.AWT(抽象窗口开发包) 当 ...
- 214 Shortest Palindrome 最短回文串
给一个字符串 S, 你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串.例如:给出 "aacecaaa",返回 "aaacecaaa ...
- 里氏替换原则中is和as分别的作用
is 是用于检查对象是否指定类型兼容 if(empls[i] is SE){ ((SE)empls).SayHi(); } as 不用强转可以直接转换 if(empls[i] is SE){ SE s ...
- Java-超市购物小票案例-详细介绍
1.1 超市购物购物小票需求分析 用户循环进行三个操作: 1.输入购买数量,代表为所购买货物的数量赋值,从而计算每项商品金额 2.打印小票,将已有数据打印 3.退出系统(因为该程序为循环操作,无法终 ...
- 面试题6:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList
题目 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 思路 使用栈依次存放输入的链表顺序的值,然后依次出栈便是链表的逆序. 代码 import java.util.ArrayList ...
- yii在Windows下安装(通过composer方式)
Composer 安装: (Composer 不是一个包管理器,它仅仅是一个依赖管理工具.它涉及 "packages" 和 "libraries",但它在每个项 ...
- Windows下使用JMeter
简介 Apache JMeter是100%纯java桌面应用程序,被设计用来测试C/S结构的软件(例如web应用程序).它可以被用来测试包括基于静态和动态资源程序的性能,例如静态文件,Java Ser ...