codeforces 848B

原题链接:http://codeforces.com/problemset/problem/848/B

题意:好多个人分别从x,y轴不同位置不同时间往垂直坐标轴方向移动,一旦相遇他们转向,问所有人的到达边缘的位置。

思路:即使相遇后没有改变方向,终点位置还是不变的。

1.首先可以根据开始移动的时间将每个人的初始位置往后移动ti单位,这样就可以看作所有人都同时开始移动了。

2.接下来,假设两个人i,j在t时刻(x, y)处相撞,那么可以推知两个人的初始位置分别为(x-t, y),(x, y-t),由此可知两个点的初始x+y(在考虑1的条件下为x+y-t)是相等的

3.如果我们画图分析一些样例,可以发现,初始x+y相等的若干个点:他们在相撞之后,最后落在边缘的位置,从左上到右上再到右下,依次和初始位置从左上到左下再到右下的顺序是一样的,即如果我们顺时针将终点标号,逆时针将x+y相等的起点标号,那么起点与对应的终点标号恰好是一样的。

那么我们可以先根据(x-t)排序并根据初始坐标逆时针排序,在最后记录答案时只需要在找到相等x+y的点(区间)之后,得到y轴出发的点的数量k,每个点对应终点就是排序好的位置往后第k个点,超出范围的取个模就行了。

AC代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 const int MAXN = 1e5 + 10;
 7 struct Node {
 8     int x, y;
 9     int val;
10     int g;
11 }node[MAXN], res[MAXN];
12 int p[MAXN];
13 bool cmp(int a, int b) {
14     if (node[a].val == node[b].val) {
15         if (node[a].x == node[b].x)
16             return node[a].y>node[b].y;
17         return node[a].x<node[b].x;
18     }
19     return node[a].val<node[b].val;
20 }
21 int main()
22 {
23     for (int i = 0;i<MAXN;i++) p[i] = i;
24     int n, w, h;
25     int pos, T, type;
26     scanf("%d %d %d", &n, &w, &h);
27     for (int i = 0;i<n;i++) {
28         scanf("%d %d %d", &type, &pos, &T);
29         if (type == 1) {
30             node[i].x = pos;
31             node[i].y = 0;
32             node[i].val = pos - T;
33         }
34         else {
35             node[i].x = 0;
36             node[i].y = pos;
37             node[i].val = pos - T;
38         }
39     }
40     sort(p, p + n, cmp);
41     node[n].val = -2*MAXN;
42     int first_y = -1, last_y = -1, first_x = -1, last_x = -1;
43     int v = node[p[0]].val, goal;
44     for (int i = 0;i<=n;i++) {
45         if (v != node[p[i]].val) {
46             int s = last_y - first_y + 1;
47             int t = last_x - first_y + 1;
48             int j = first_y;
49             if (first_y == -1 && last_y == -1) {
50                 s = 0;
51                 j = first_x;
52             }
53             if (first_x == -1 && last_x == -1) {
54                 s = 0;
55                 //j=first_y;
56             }
57             for (;j <= last_x;j++) {
58                 goal = j + s;
59 
60                 if (goal>last_x) goal -= t;//这个操作相当于取模
61                 node[p[j]].g = p[goal];
62             }
63 
64             v = node[p[i]].val;
65             first_y = -1, last_y = -1, first_x = -1, last_x = -1;
66         }
67         if (node[p[i]].x == 0) {
68             if (first_y == -1)    first_y = i;
69             last_y = i;
70         }
71         else {
72             if (first_x == -1) first_x = i;
73             
74         }last_x = i;//把last_x拿到外面比较妥当,防止判断j<=last_x时last_x==-1的情况
75     }
76     for (int i = 0;i<n;i++) {
77         goal = node[p[i]].g;
78         if (node[goal].x == 0) res[p[i]].x = w;
79         else res[p[i]].x = node[goal].x;
80 
81         if (node[goal].y == 0) res[p[i]].y = h;
82         else res[p[i]].y = node[goal].y;
83     }
84     for (int i = 0;i<n;i++)
85         printf("%d %d
", res[i].x, res[i].y);
86     
87 }
原文地址:https://www.cnblogs.com/MasterSpark/p/7482204.html