题目链接:http://codeforces.com/problemset/problem/452/B
题目意思:给出一个长为n,宽为 m 的矩形,要从这里面(包括边上)找出4个不同的点,使得以某一个点出发,直到四个点都经过后的连线最长。
看到题目中的两个样例,很天真的以为对于一般的n和m(至少有一个不为0),就好像test1那样输出,还特意分四个象限来做呐;而如果 n 或 m 有一个为0,则好像test2 那样处理,于是交了,过不了test3;于是又加多个特判,n == m & n == 1,因为它跟一般的n 和 m 的处理方式是不同的(当然四个象限的值又要再次讨论啦~~)。紧接着,test5过不了,再也不知道怎么侥幸了,只能看别人代码学人思路啦,本来想先看tutorial的,不过好像木有啦~~~几何题!!!
为了不侵犯别人的知识产权,这个代码是这个人的:
7260620 | 2014-07-27 21:15:06 | sevenkplus | 452B - 4-point polyline | GNU C++ | Accepted | 15 ms | 0 KB |
他主要的思路就是暴力!!!枚举16个点中的任意四个,求出最长的距离,保存这四个点的坐标就是答案。
他的操作步骤好厉害,长知识噜^_^ 。尤其是将16个点放在一个嵌有pair 的set里面一个一个枚举(16个点是指,首先是右上角:(n, m),(n, m-1)(n-1, m-1),(n-1, m);右下角:(n, 1), (n, 0), (n-1, 0), (n-1, 1);左下角:(1, 1), (1, 0), (0, 0),(0, 1);左上角:(1, m), (1, m-1), (0, m-1), (0, m))
之所以可以这样做,是因为对于一个矩形来讲,最长的无非就是对角线的长度嘛。16个点就可以覆盖所有情况啦。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cmath> 6 #include <set> 7 using namespace std; 8 9 #define mp make_pair 10 #define fi first 11 #define se second 12 typedef pair<int, int> PII; 13 typedef set<PII>:: iterator PIIP; 14 15 set<PII> A; 16 PII a1, a2, a3, a4; 17 PIIP i, j, k, l; 18 19 int n, m; 20 21 void addnode(int x, int y) 22 { 23 if (x >= 0 && x <= n && y >= 0 && y <= m) 24 A.insert(mp(x, y)); 25 } 26 27 double dist(PII x, PII y) 28 { 29 return sqrt((x.fi-y.fi)*(x.fi-y.fi) + (x.se-y.se)*(x.se-y.se)); 30 } 31 32 int main() 33 { 34 while (scanf("%d%d", &n, &m) != EOF) 35 { 36 A.clear(); 37 // 右上角 38 addnode(n, m); 39 addnode(n, m-1); 40 addnode(n-1, m-1); 41 addnode(n-1, m); 42 // 右下角 43 addnode(n, 1); 44 addnode(n, 0); 45 addnode(n-1, 0); 46 addnode(n-1, 1); 47 // 左下角 48 addnode(1, 1); 49 addnode(1, 0); 50 addnode(0, 0); 51 addnode(0, 1); 52 // 左上角 53 addnode(1, m); 54 addnode(1, m-1); 55 addnode(0, m-1); 56 addnode(0, m); 57 58 double tmp = -1; 59 for (i = A.begin(); i != A.end(); i++) 60 { 61 for (j = A.begin(); j != A.end(); j++) 62 { 63 for (k = A.begin(); k != A.end(); k++) 64 { 65 for (l = A.begin(); l != A.end(); l++) 66 { 67 if (i == j || i == k || i == l || j == k || j == l || k == l) 68 continue; 69 double t = dist(*i, *j) + dist(*j, *k) + dist(*k, *l); 70 if (t > tmp) 71 { 72 tmp = t; 73 a1 = *i; 74 a2 = *j; 75 a3 = *k; 76 a4 = *l; 77 } 78 } 79 } 80 } 81 } 82 printf("%d %d ", a1.fi, a1.se); 83 printf("%d %d ", a2.fi, a2.se); 84 printf("%d %d ", a3.fi, a3.se); 85 printf("%d %d ", a4.fi, a4.se); 86 } 87 return 0; 88 }
(这个是我昨晚看完今日默写的,虽然最后还是有点点瑕疵需要看回他的来修改,不过好开心学到这么厉害的写法)