Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
二分 216K 1141MS 注意不要用浮点数就可以了先将点排序,外层 x 递增,选定最左端点 p1 后第二层循环寻找右端点 p2,从而确定对角线投影在 x, y 上的长度,根据这个确定另外两个点坐标,二分搜索 p1 到 p2 之间的点。 注意以下几点: 将所有输入的坐标值乘 2,确保在计算另两个点的时候得到整数。 将 x 坐标的第一个元素的索引单独储存起来,方便按 x 递增。 注意二分搜索的范围只在 p1 到 p2 之间,即提高效率,也避免重复。 #include <cstdio> #include <algorithm> using namespace std; #define MAXN 1000 typedef pair<int, int> P; P _ns[MAXN]; int _xs[MAXN + 1]; int _n, _x, _res; int Ipt() { if (scanf("%d", &_n), !_n) { return EOF; } _x = 0, _res = 0; int i, f, s; for (i = 0; i < _n; ++i) { scanf("%d%d", &f, &s); _ns[i].first = (f << 1); // 坐标翻倍 _ns[i].second = (s << 1); } sort(_ns, _ns + _n); int preX = _ns[0].first; _xs[_x++] = 0; for (i = 1; i < _n; ++i) // 储存 x 索引 { if (_ns[i].first != preX) { _xs[_x++] = i; preX = _ns[i].first; } } _xs[_x] = _n; return 0; } inline void Opt() { printf("%d\n", _res); } void Test() { int i, j, k; int jEnd; int x1, x2, x3, x4, y1, y2, y3, y4; int xMid, yMid, xSub, ySub; P *p = NULL, *pEnd = NULL; bool flag = false; for (i = 0; i < _x; ++i) { jEnd = _xs[i + 1]; for (j = _xs[i]; j < jEnd; ++j) { x1 = _ns[j].first; y1 = _ns[j].second; for (k = i + 1; k < _x; ++k) { p = _ns + _xs[k], pEnd = _ns + _xs[k + 1]; while (p != pEnd) { x2 = p->first; y2 = p->second; xSub = (x2 - x1) / 2; xMid = x1 + xSub; yMid = (y1 + y2) / 2; ySub = (y2 - y1) / 2; x3 = xMid - ySub; y3 = yMid + xSub; x4 = xMid + ySub; y4 = yMid - xSub; if (binary_search(_ns + j + 1, p, P(x3, y3)) && binary_search(_ns + j + 1, p, P(x4, y4))) // 注意搜索范围 { ++_res; } ++p; } } } } } int main() { while (EOF != Ipt()) { Test(); Opt(); } return 0; } 2002 Squares (216K 1141MS) Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator