1. 程式人生 > >codeforces 848B - Rooter's Song(構造+幾何)

codeforces 848B - Rooter's Song(構造+幾何)

不變 找到 size != targe i++ algorithm 題意 con

原題鏈接: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\n", res[i].x, res[i].y); 86 87 }

codeforces 848B - Rooter's Song(構造+幾何)