LightOJ 1058 - Parallelogram Counting 几何思维
http://www.lightoj.com/volume_showproblem.php?problem=1058
题意:给你顶点,问能够成多少个平行四边形。
思路:开始想使用长度来扫描有多少根,但是好像坐标太大似乎不可行。其实我们可以通过找所有线段的中点的重合个数来计算有几个平行四边形,这种通过别的性质来判断几何关系的思维是解几何题的基础,当作入门?
/** @Date : 2016-12-02-21.49 * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : */ #include<bits/stdc++.h> #define LL long long #define PII pair #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e6+20; struct yuu { double x; double y; bool operator == (const yuu &a) const { return (a.x == this->x) && (a.y == this->y); } }s[1010], t[N]; int cmp(yuu a, yuu b) { if(a.x != b.x) return a.x > b.x; return a.y > b.y; } map<pair<double, double> , int>q; int main() { int T; int cnt = 0; cin >> T; while(T--) { q.clear(); int n; scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%lf%lf", &s[i].x, &s[i].y); int c = 0; for(int i = 1; i <= n; i++) { for(int j = i + 1; j <= n; j++) { struct yuu p; double x = 0, y = 0; p.x = s[i].x + s[j].x; p.y = s[i].y + s[j].y; t[c++] = p; //q[MP(x, y)]++; } } sort(t, t + c, cmp); LL ans = 0; LL k = 0; for(int i = 0; i < c; i++) { //cout << t[i].x << " " << t[i].y << endl; if(t[i] == t[i + 1]) k++; else ans+=(k + 1) *k /2, k = 0; } //ans += (k + 1)* k / 2; /*for(auto i = q.begin(); i != q.end(); i++) { ans += (i->se)*(i->se - 1)/2; }*/ /*map<pair<double, double>, int>::iterator it; for(it = q.begin(); it != q.end(); it++) ans += (it->se)*(it->se - 1) / 2;*/ printf("Case %d: %lld\n", ++cnt, ans); } return 0; } //判断对角线中点出现次数。