Eureka
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1638 Accepted Submission(s): 453
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,v∈P,u≠v) are called best pair, if for every w∈P , f(u,v)≥g(u,v,w) , where f(u,v)=(xu−xv)2+(yu−yv)2−−−−−−−−−−−−−−−−−−−√ and g(u,v,w)=f(u,v)+f(v,w)+f(w,u)2 .
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,v∈P,u≠v) are called best pair, if for every w∈P , f(u,v)≥g(u,v,w) , where f(u,v)=(xu−xv)2+(yu−yv)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 (1≤n≤1000) -- then number of points.
Each of the following n lines contains two integers xi and yi (−109≤xi,yi≤109) -- coordinates of the i -th point.
The first line contains an integer n (1≤n≤1000) -- then number of points.
Each of the following n lines contains two integers xi and yi (−109≤xi,yi≤109) -- 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
Recommend
wange2014
题意:题目的公式化简之后就可以发现只要set里面的点全是共线的就是best set,然后,不难用数学推出只要统计出线上有多少个点,那么集合的数目可以求出来,题目还有重点的问题必须解决,所以还是很有难度的。经过围巾师兄的指点,我终于会做了这道题。下面给代码。
#include<iostream> #include<stack> #include<cstring> #include<map> #include<string> #include<queue> #include<algorithm> #include<cstdio> #include<utility> using namespace std; #define maxn 1005 #define MOD 1000000007 typedef long long LL; struct node { int x, y; }p[maxn];//储存点 int gcd(int a, int b) { if (!b) return a; else return gcd(b, a%b); } LL quitemod(LL a, LL b) { LL ans = 1; a = a%MOD; while (b > 0) { if (b % 2 == 1) ans = (ans*a) % MOD; b = b / 2; a = (a*a) % MOD; } return ans; } bool cmp(node a, node b) { return a.x < b.x || (a.x == b.x&&a.y < b.y); } int main() { int t; scanf("%d", &t); while (t--) { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d%d", &p[i].x, &p[i].y); } sort(p + 1, p + n + 1, cmp); LL sum = 0;//统计有多少个集合 for (int i = 1; i <= n; i++) { map<pair<int, int>, LL>m;//储存一条线上有个点,pair储存斜率 LL tj = 1;//统计重点 for (int j = i + 1; j <= n; j++) { int fz = p[j].y - p[i].y; int fm = p[j].x - p[i].x; if (!fz&&!fm) { tj++; continue; } int x = gcd(fz, fm); if (x != 0) { fz /= x; fm /= x; } m[make_pair(fz, fm)]++; } if (tj > 1) { sum += quitemod(2, tj - 1) - 1; sum %= MOD; } map<pair<int, int>, LL>::iterator it; for (it = m.begin(); it != m.end(); it++) { sum = (sum + (quitemod(2, it->second) - 1) *quitemod(2, tj - 1) % MOD) % MOD; } } printf("%lld\n", sum); } }