【HDU5738 2016 Multi-University Training Contest 2E】【平面點數計數 共線判定】Eureka 平面有多少個集合滿足貢獻
Eureka
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2448 Accepted Submission(s): 718
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
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1010, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int casenum, casei;
int n;
struct A
{
int x, y;
bool operator < (const A&b)const
{
if (x != b.x)return x < b.x;
return y < b.y;
}
}a[N], b[N];
int bit[N];
int gcd(int x, int y)
{
return y == 0 ? x : gcd(y, x%y);
}
void add(int &x, int y)
{
if ((x += y) >= Z)x -= Z;
}
void datamaker()
{
freopen("c://test//input.in", "w", stdout);
int T = 100; printf("%d\n", T);
while (T--)
{
int n = rand() % 4 + 1; printf("%d\n", n);
for (int i = 1; i <= n; ++i)
{
int x = rand() % 5 + 1;
int y = rand() % 5 + 1;
printf("%d %d\n", x, y);
}
}
}
int main()
{
//datamaker(); return 0;
//fre();
bit[0] = 1; for (int i = 1; i <= 1000; i++) bit[i] = (bit[i - 1] << 1) % Z;
scanf("%d", &casenum);
for (casei = 1; casei <= casenum; ++casei)
{
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d%d", &a[i].x, &a[i].y);
sort(a + 1, a + n + 1);
int ans = 0;
for (int i = 1; i <= n; ++i)
{
int same = 0;
int g = 0;
for (int j = i + 1; j <= n; ++j)
{
if (a[j].x == a[i].x && a[j].y == a[i].y)
{
add(ans, bit[same++]);
}
else
{
int x = a[j].x - a[i].x;
int y = a[j].y - a[i].y;
int g_ = gcd(x, y);
b[++g] = { x / g_, y / g_ };
}
}
sort(b + 1, b + g + 1);
int line = 0;
for (int j = 1; j <= g; ++j)
{
if (b[j].x != b[j - 1].x || b[j].y != b[j - 1].y)line = 0;
add(ans, (LL)bit[same] * bit[line++] % Z);
}
}
printf("%d\n", ans);
}
return 0;
}
/*
【trick&&吐槽】
讀題是AC的基礎啊。
這道題不光做法常數大TLE了,讀題轉化也出了問題。
= =#我是該感到開心還是難過呢>.<
1,固定一個點的思路特別棒。
2,來一個點就算這個點的貢獻的做法,十分精妙而優美。
【題意】
平面上有n個點,
問你有多少個點集滿足——
點集上至少有2個點,使得該集合的其他點都在這2點所連線段的區間範圍內。
(這是轉化後的問題)
【型別】
平面點數計數
【分析】
我們計數的時候如何使得不重複計數呢?
一個很值得采納的做法,是列舉、固定一個點。
這道題就是這個樣子——
我們可以列舉一個點,這個點一定在集合內,然後再考慮其它點的相關性。
1,如果只涉及關於重點的集合,顯然對答案的貢獻是2^(與之成為重點的點個數)-1
2,如果還涉及非重點的集合,對答案的貢獻是(2^(與之成為重點的點個數))*(2^(共線點數)-1)
【時間複雜度&&優化】
O(n^2logn)
*/
相關文章
- HDU-2016 Multi-University Training Contest 3-Sqrt Bo-大數開方AI
- 2018 Multi-University Training Contest 3 - HDU ContestAI
- HDU 6039 Gear Up(2017 Multi-University Training Contest 1)AI
- 發展數字經濟 貢獻中國智慧
- 5 個提升你開源專案貢獻者基數的方法
- HDU 5235 Friends (2015 Multi-University Training Contest 2 搜尋+剪枝)AI
- 滿足這幾點開通智慧數字化經營不是難題
- 2018 Multi-University Training Contest 9----hdu 6415 Rikka with Nash EquilibriumAIUI
- 【HDU5734 2016 Multi-University Training Contest 2A】【公式代入推導】Acperience n維向量各有加減最小模長AI公式
- 小組貢獻統計表
- python演算法 - 快速尋找滿足條件的兩個數Python演算法
- 演算法之陣列——共直線的最多點數演算法陣列
- 蘋果每位員工一年能貢獻多少收入?蘋果
- 【HDU5735 2016 Multi-University Training Contest 2B】【暴力做法 + 折半法】Born Slippy 祖先鏈的最大運算權值AI
- 數字音樂論壇:數字音樂產業25%的人群貢獻75%的銷售額產業
- [Lucas定理] 集合計數
- 蘋果的貢獻蘋果
- 零起點的開源社群貢獻指南
- 求陣列中是否存在滿足特定和的兩個數字(python & Js)陣列PythonJS
- 計算兩個NSDate之間,相隔多少秒數
- 快速滿足個性化業務需求的低程式碼平臺
- 福布斯:商業無人機行業將為美國經濟貢獻數十億美元無人機行業
- MySQL 預設最大連線數是多少?MySql
- Android開發者要換多少次工作,才能心滿意足?Android
- iOS裝置8年總銷量超11億臺你貢獻了多少?iOS
- 智慧數字展廳的建設方案需要滿足的條件
- C++列舉演算法之滿足條件的整數C++演算法
- 雙層無線接入網路滿足不同無線需求
- 鋼鐵行業智慧供應商系統滿足鋼企數字化營銷剛需,實現多方互利共贏局面行業
- (未完工)Contest7516 - 平面圖
- 一個Java方法能使用多少個引數?Java
- 1354: 素數判定(C語言)C語言
- Oracle引數修改後的生效判定Oracle
- 素數判定演算法 初級演算法
- 團隊貢獻分分配
- AtCoder Beginner Contest 370 E(計數 + DP)
- 解析智和網管平臺SugarNMS等保2.0滿足的控制點內容
- 弗羅斯特:自動駕駛每年將為英國經濟貢獻數百億英鎊自動駕駛