hdu5738 Eureka(数学)

本文介绍了一种解决平面上点共线问题的算法实现,通过使用斜率映射到整数对的方法来避免浮点误差,同时考虑了重复点的情况,并通过计算组合数来得出最终的共线点集数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:统计平面内有多少个点共线,有重点

思路:显然没有重点的时候是个水题,这里统计共线我是用了斜率存进map里面,由于直接除会是double很容易挂,所以直接map<pair<>,int>这样来处理就可以解决了,然后算一下重点的贡献和不重点的贡献就可以了


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
const int mod = 1e9+7;
#define LL long long
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL qpow(LL a,LL b)
{
	if(b<0)
		return 0;
	LL ans = 1;
	a%=mod;
	for(;b;b>>=1,a=(a*a)%mod)
		if(b&1)
			ans = (ans*a)%mod;
	return ans;
}
struct Node
{
	LL x,y;
}point[maxn];
bool cmp(Node a,Node b)
{
	if(a.x==b.x)
		return a.y<b.y;
	return a.x<b.x;
}
map<pair<LL,LL>,int >vis;
int main()
{
    int T;
	scanf("%d",&T);
	while(T--)
	{
		vis.clear();
		LL ans = 0;
		int n;
		scanf("%d",&n);
		for(int i = 1;i<=n;i++)
			scanf("%lld%lld",&point[i].x,&point[i].y);
		sort(point+1,point+1+n,cmp);
        for(int i = 1;i<=n;i++)
		{
			vis.clear();
			LL res = 1;
			for(int j = i+1;j<=n;j++)
			{
                if(point[i].x==point[j].x && point[i].y==point[j].y)
					res++;
				else
				{
					LL dx = point[j].x-point[i].x;
					LL dy = point[j].y-point[i].y;
					LL gg = gcd(dx,dy);
					if(gg!=0)
					{
						dx/=gg;
					    dy/=gg;
					}
					vis[make_pair(dx,dy)]++;
				}
			}
			if(res>1)
			{
				ans+=(qpow(2,res-1)-1)%mod;
				ans%=mod;
			}
			LL cnt = 0;
			for(map<pair<LL,LL>,int>::iterator it = vis.begin();it!=vis.end();it++)
			{
				LL cnt=(it->second);
				ans = (ans+((qpow(2,cnt)-1)*(qpow(2,res-1)))%mod)%mod;
			}
		}
		printf("%lld\n",ans);
	}
}



Problem Description
Professor Zhang draws  n  points on the plane, which are conveniently labeled by  1,2,...,n . The  i -th point is at  (xi,yi) . Professor Zhang wants to know the number of best sets. As the value could be very large, print it modulo  109+7 .

A set  P  ( P  contains the label of the points) is called best set if and only if there are at least one best pair in  P . Two numbers  u  and  v   (u,vP,uv)  are called best pair, if for every  wP f(u,v)g(u,v,w) , where  f(u,v)=(xuxv)2+(yuyv)2  and  g(u,v,w)=f(u,v)+f(v,w)+f(w,u)2 .
 

Input
There are multiple test cases. The first line of input contains an integer  T , indicating the number of test cases. For each test case:

The first line contains an integer  n   (1n1000)  -- then number of points.

Each of the following  n  lines contains two integers  xi  and  yi   (109xi,yi109)  -- coordinates of the  i -th point.
 

Output
For each test case, output an integer denoting the answer.
 

Sample Input
  
3 3 1 1 1 1 1 1 3 0 0 0 1 1 0 1 0 0
 

Sample Output
  
4 3 0
 

Author
zimpha
 

Source


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值