HDU 3629-Convex找凸四边形个数(扫描+二分/two pointers)
2016-04-08 13:05
453 查看
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11713
题意:给n个点,无三点共线,求凸四边形个数。
对应凸四边形,有着一个 凹四边形,其实凹四边形,就相当于一个三角形,内部包含了一个点,则这样就可以构成一个凹四边形。 内部包含x个点,则x个凹四边形。
则题目转化为求有多少个凹四边形,再转为 每个三角形内部有多少个点
就和这题一样了
http://blog.csdn.net/viphong/article/details/51095501
按极角序扫描得到 每个三角形内部多少个点,然后 c(n,4)-它便是答案了
注意加了eps=1e6反而wa,,不加或eps=1e-12都能过。。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=1e-12;
__int64 min(__int64 a,__int64 b)
{return a<b?a:b;}
__int64 max(__int64 a,__int64 b)
{return a>b?a:b;}
struct node
{
int x,y;
node(){}
double jijiao;
node(int a,int b){x=a,y=b;}
};
node tm[1255];
node tmp[2455];
bool cmp(node a,node b)
{
return a.jijiao<b.jijiao;
}
int n;
__int64 count(__int64 x)
{
int i;
int idx=1;
for (i=1;i<=n;i++)
{
if (i==x)continue;
tmp[idx].x=tm[i].x-tm[x].x;
tmp[idx].y=tm[i].y-tm[x].y;
tmp[idx].jijiao=atan2(tmp[idx].y,tmp[idx].x);
tmp[idx+n-1].jijiao=tmp[idx].jijiao+2*pi;
idx++;
}
sort(tmp+1,tmp+1+(2*n-2),cmp);
node tp;
__int64 res=0;
for (i=1;i<n;i++)
{
tp.jijiao=tmp[i].jijiao+pi+eps;
int it=upper_bound(tmp+1,tmp+1+2*n-2,tp,cmp)-tmp;
int cnt=it-i-1;
res+= cnt*(cnt-1)/2;
}
int s= (n-1);
s*=(n-2)*(n-3);
s/=6;
return s-res;
}
int main()
{
__int64 cnt=1;
__int64 i;
int t;cin>>t;
while(t--)
{
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d%d",&tm[i].x,&tm[i].y);
__int64 ans=0;
for (i=1;i<=n;i++)
ans+=count(i);
__int64 tmp=n;
tmp*=n-1;
tmp*=n-2;
tmp*=n-3;
tmp/=24;
ans=tmp-ans;
printf("%I64d\n",ans);
}
return 0;
}
题意:给n个点,无三点共线,求凸四边形个数。
对应凸四边形,有着一个 凹四边形,其实凹四边形,就相当于一个三角形,内部包含了一个点,则这样就可以构成一个凹四边形。 内部包含x个点,则x个凹四边形。
则题目转化为求有多少个凹四边形,再转为 每个三角形内部有多少个点
就和这题一样了
http://blog.csdn.net/viphong/article/details/51095501
按极角序扫描得到 每个三角形内部多少个点,然后 c(n,4)-它便是答案了
注意加了eps=1e6反而wa,,不加或eps=1e-12都能过。。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=1e-12;
__int64 min(__int64 a,__int64 b)
{return a<b?a:b;}
__int64 max(__int64 a,__int64 b)
{return a>b?a:b;}
struct node
{
int x,y;
node(){}
double jijiao;
node(int a,int b){x=a,y=b;}
};
node tm[1255];
node tmp[2455];
bool cmp(node a,node b)
{
return a.jijiao<b.jijiao;
}
int n;
__int64 count(__int64 x)
{
int i;
int idx=1;
for (i=1;i<=n;i++)
{
if (i==x)continue;
tmp[idx].x=tm[i].x-tm[x].x;
tmp[idx].y=tm[i].y-tm[x].y;
tmp[idx].jijiao=atan2(tmp[idx].y,tmp[idx].x);
tmp[idx+n-1].jijiao=tmp[idx].jijiao+2*pi;
idx++;
}
sort(tmp+1,tmp+1+(2*n-2),cmp);
node tp;
__int64 res=0;
for (i=1;i<n;i++)
{
tp.jijiao=tmp[i].jijiao+pi+eps;
int it=upper_bound(tmp+1,tmp+1+2*n-2,tp,cmp)-tmp;
int cnt=it-i-1;
res+= cnt*(cnt-1)/2;
}
int s= (n-1);
s*=(n-2)*(n-3);
s/=6;
return s-res;
}
int main()
{
__int64 cnt=1;
__int64 i;
int t;cin>>t;
while(t--)
{
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d%d",&tm[i].x,&tm[i].y);
__int64 ans=0;
for (i=1;i<=n;i++)
ans+=count(i);
__int64 tmp=n;
tmp*=n-1;
tmp*=n-2;
tmp*=n-3;
tmp/=24;
ans=tmp-ans;
printf("%I64d\n",ans);
}
return 0;
}
相关文章推荐
- 常见jquery函数集合总结
- 唯品会——java开发实习生机试
- 几种最常见的网站盈利模式分析
- Delphi 实现Ini文件参数与TEdit和TCheckBox绑定(TSimpleParam)
- android数据存储——文件存储
- parcelable接口
- 剑指offer-面试题37.两个链表的第一个公共结点
- 原生js和jquery实现图片轮播特效
- USB学习笔记连载(二十):FX2LP如何实现高速和全速切换(转载)
- HDU S NIM 求sg函数
- 谷歌离线地图API解析
- DataInputStream和DataOutputStream使用方法细节探讨
- 汉堡包1.0
- 内存溢出OOM与内存泄漏ML
- 剑指offer-面试题32.从1到n整数中1出现的次数
- ZOJ1586 QS Network
- runLoop 添加timer的正确方式 (ios oc)
- ios多工程依赖
- OSI七层参考模型 TCP与UDP、IP、ICMP 如何编写Socket套接字? 端口号
- 常见面试题整理+网易实习生面试