CodeForces - 13D Triangles
2015-12-04 22:17
453 查看
本题是向量叉积的应用,应用向量叉积可以判断一个点是否在三角形内部。
向量积 axb =|a|*|b|*sin<a,b>
当b在a的逆时针方向,向量积是正数,反之,是负数。
由图可知三角形内部的点都在三角形边的同一侧。
可以结合此性质解决本题。
绿色和红色区域可以根据三角形行走的方向相消为0
#include<iostream>
#include<cstring>
#include<cmath>
#include<assert.h>
#include<stdio.h>
using namespace std;
typedef __int64 lld;
const int INF=1000000000;
struct P
{
lld x,y;
P(){};
P(lld x,lld y):x(x),y(y){};
P operator -(const P & b)const
{
P tmp(x-b.x,y-b.y);
return tmp;
}
};
lld cross(P a,P b)
{
return a.x*b.y-a.y*b.x;
}
P red[505],blue[505];
int cnt[505][505];
int main()
{
int i,j,k;
int N,M;
lld x,y;
memset(cnt,0,sizeof(cnt));
cin>>N>>M;
assert(N>=0&&N<=500);
assert(M>=0&&M<=500);
for(i=0;i<N;i++)
{
cin>>x>>y;
assert(x>=-INF&&x<=INF);
assert(y>=-INF&&y<=INF);
red[i]=P(x,y);
}
for(i=0;i<M;i++)
{
cin>>x>>y;
assert(x>=-INF&&x<=INF);
assert(y>=-INF&&y<=INF);
blue[i]=P(x,y);
}
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
if(i==j||red[i].x>red[j].x)continue;
for(k=0;k<M;k++)
{
if(blue[k].x>=red[i].x&&blue[k].x<red[j].x&&cross(blue[k]-red[i],red[j]-red[i])>0)
cnt[i][j]++;
}
cnt[j][i]=-cnt[i][j];
}
}
int ans=0;
for(i=0;i<N;i++)
{
for(j=i+1;j<N;j++)
for(k=j+1;k<N;k++)
{
if(cnt[i][j]+cnt[j][k]+cnt[k][i]==0)
ans++;
}
}
cout<<ans<<endl;
return 0;
}
向量积 axb =|a|*|b|*sin<a,b>
当b在a的逆时针方向,向量积是正数,反之,是负数。
由图可知三角形内部的点都在三角形边的同一侧。
可以结合此性质解决本题。
绿色和红色区域可以根据三角形行走的方向相消为0
#include<iostream>
#include<cstring>
#include<cmath>
#include<assert.h>
#include<stdio.h>
using namespace std;
typedef __int64 lld;
const int INF=1000000000;
struct P
{
lld x,y;
P(){};
P(lld x,lld y):x(x),y(y){};
P operator -(const P & b)const
{
P tmp(x-b.x,y-b.y);
return tmp;
}
};
lld cross(P a,P b)
{
return a.x*b.y-a.y*b.x;
}
P red[505],blue[505];
int cnt[505][505];
int main()
{
int i,j,k;
int N,M;
lld x,y;
memset(cnt,0,sizeof(cnt));
cin>>N>>M;
assert(N>=0&&N<=500);
assert(M>=0&&M<=500);
for(i=0;i<N;i++)
{
cin>>x>>y;
assert(x>=-INF&&x<=INF);
assert(y>=-INF&&y<=INF);
red[i]=P(x,y);
}
for(i=0;i<M;i++)
{
cin>>x>>y;
assert(x>=-INF&&x<=INF);
assert(y>=-INF&&y<=INF);
blue[i]=P(x,y);
}
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
{
if(i==j||red[i].x>red[j].x)continue;
for(k=0;k<M;k++)
{
if(blue[k].x>=red[i].x&&blue[k].x<red[j].x&&cross(blue[k]-red[i],red[j]-red[i])>0)
cnt[i][j]++;
}
cnt[j][i]=-cnt[i][j];
}
}
int ans=0;
for(i=0;i<N;i++)
{
for(j=i+1;j<N;j++)
for(k=j+1;k<N;k++)
{
if(cnt[i][j]+cnt[j][k]+cnt[k][i]==0)
ans++;
}
}
cout<<ans<<endl;
return 0;
}
相关文章推荐
- xcode中设置ios9应用程序图标和启动图
- Lucene初学(二)
- Linux常用命令
- linux安装交叉编译器
- MyBatis的学习总结
- 操作系统概念(第八章) 内存管理(一)
- web项目返回界面的结果显示为乱码的解决方法
- SQL存储过程和我们的试图 的操作
- Linux上Crontab详解
- Castle Activerecord多数据库如何配置详解
- Lowest Common Ancestor of a Binary Search Tree
- 快速幂取模(POJ 1995)
- mipi协议中文详解
- 汉诺塔
- crontab
- HDU 4325&& nyoj 600 Flowers【线段树+坐标离散化】
- Svn内外网切换技巧
- Windows 8安装Open edX
- 带你走进ajax(2)
- 初学Linux的一些理解及简单介绍