LA 4064 Magnetic Train Tracks

1.题目描述:点击打开链接

2.解题思路:本题利用减法原理解决。根据题意,我们可以尝试寻找钝角三角形的个数,那么只需要从C(n,3)中把这部分减掉,就是最后的答案了。注意到钝角三角形的特点是最大的角度大于90度小于180度。我们可以先让每个点都当做一次坐标原点,计算出其他点相对于该点的极角,并把这n-1个从小到大排序,那么非法的情况实际上是介于(90,270)之间的极角,这个很容易通过二分搜索查找到边界。边界相减就是以第i个点为参考坐标时候,钝角三角形的个数。这样,本题即可得以解决。

3.代码:

#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

#define rep(i,n) for(int i=0;i<(n);i++)
#define me(s) memset(s,0,sizeof(s))
#define pb push_back
#define lid (id<<1)
#define rid (id<<1|1)

typedef long long ll;
typedef pair<int,int> P;

const int N = 1200 + 10;
const double PI = acos(-1.0);
const double eps = 1e-10;

int dcmp(double x)
{
	if (fabs(x)<eps)return 0;
	return x<0 ? -1 : 1;
}
struct Point
{
	double x, y;
	double ang;
	Point() {}
	Point(double x, double y) :x(x), y(y) {}
	bool operator<(const Point&rhs)const
	{
		return ang<rhs.ang;
	}
};

typedef Point Vector;
Vector operator+(Vector a, Vector b) { return Vector(a.x + b.x, a.y + b.y); }
Vector operator-(Vector a, Vector b) { return Vector(a.x - b.x, a.y - b.y); }

Point a[N];
double angle[N*N];
int n;

int main()
{
	int rnd = 0;
	while (~scanf("%d", &n)&&n)
	{
		for (int i = 0; i<n; i++)
		{
			scanf("%lf%lf", &a[i].x, &a[i].y);
		}
		int cnt=0;
		ll ans=0;
		for(int i=0;i<n;i++)
		{
		    cnt=0;
		    for(int j=0;j<n;j++)
                if(j!=i)
                angle[cnt++]=atan2(a[j].y-a[i].y,a[j].x-a[i].x);
            sort(angle,angle+cnt);
            for(int i=0;i<cnt;i++)
            {
                double e1=angle[i]+PI/2,e2=angle[i]+3*PI/2;
                int s=lower_bound(angle,angle+cnt,e1-eps)-angle;//注意:用lower_bound查找e1-eps
                int t=upper_bound(angle,angle+cnt,e2+eps)-angle;//同上
                ans+=t-s;
            }
		}
        ans=(ll)n*(n-1)*(n-2)/6-ans;
		printf("Scenario %d:\n", ++rnd);
		printf("There are %lld sites for making valid tracks\n", ans);
	}
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值