题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6147
果然是原题之星…原题链接:http://contest.felk.cvut.cz/14prg/solved/self/
确实很容易发现,第一次覆盖一定是与轨迹上的前8段(或者更 少)中的某一段。
1 /* 2 * CTU Open Contest 2014 3 * Problem solution: Self Intersection 4 * 5 * Author: Michal "Mimino" Danilak 6 */ 7 8 #include <cstdio> 9 #include <algorithm> 10 using namespace std; 11 12 const int MAX = 1000007, dx[] = { 0, 1, 0, -1 }, dy[] = { 1, 0, -1, 0 }; 13 int N, a[MAX]; 14 15 struct Point 16 { 17 int x, y; 18 Point(int _x = 0, int _y = 0) : 19 x(_x), y(_y) {} 20 } points[MAX]; 21 22 // true, if intervals [a,b] and [c,d] have non-empty intersection 23 bool overlap(int a, int b, int c, int d) 24 { 25 if (a > b) swap(a, b); 26 if (c > d) swap(c, d); 27 return !(b < c || d < a); 28 } 29 30 // true if line segments [a1,a2] and [b1,b2] have non-empty intersection 31 bool intersect(Point a1, Point a2, Point b1, Point b2) 32 { 33 bool is_vertical_a = (a1.x == a2.x), is_vertical_b = (b1.x == b2.x); 34 if (is_vertical_a && is_vertical_b) 35 return a1.x == b1.x && overlap(a1.y, a2.y, b1.y, b2.y); 36 if (!is_vertical_a && !is_vertical_b) 37 return a1.y == b1.y && overlap(a1.x, a2.x, b1.x, b2.x); 38 // make a horizontal and b vertical 39 if (is_vertical_a) 40 { 41 swap(a1, b1); 42 swap(a2, b2); 43 } 44 return !( 45 max(a1.x, a2.x) < b1.x || 46 min(a1.x, a2.x) > b1.x || 47 max(b1.y, b2.y) < a1.y || 48 min(b1.y, b2.y) > a1.y); 49 } 50 51 int solve() 52 { 53 int x = 0, y = 0; 54 for (int i = 0; i < N; ++i) 55 { 56 x += dx[i & 3] * a[i]; 57 y += dy[i & 3] * a[i]; 58 points[i + 1].x = x; 59 points[i + 1].y = y; 60 for (int j = max(0, i - 8); j < i - 2; ++j) 61 if (intersect(points[j], points[j + 1], points[i], points[i + 1])) 62 return i; 63 } 64 return -1; 65 } 66 67 int main() 68 { 69 int T; 70 scanf("%d", &T); 71 while(T--) { 72 scanf("%d", &N); 73 for (int i = 0; i < N; ++i) 74 scanf("%d", a + i); 75 int result = solve(); 76 if (result == -1) 77 printf("Catch you "); 78 else 79 printf("%d ", result+1); 80 } 81 82 return 0; 83 }