CF#335 Board Game
You are playing a board card game. In this game the player has two characteristics, x and y — the white magic skill and the black magic skill, respectively. There are n spell cards lying on the table, each of them has four characteristics, ai, bi, ci and di. In one move a player can pick one of the cards and cast the spell written on it, but only if first two of it's characteristics meet the requirement ai ≤ x and bi ≤ y, i.e. if the player has enough magic skill to cast this spell. However, after casting the spell the characteristics of a player change and become equal to x = ci and y = di.
At the beginning of the game both characteristics of a player are equal to zero. The goal of the game is to cast the n-th spell. Your task is to make it in as few moves as possible. You are allowed to use spell in any order and any number of times (for example, you may not use some spells at all).
The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of cards on the table.
Each of the next n lines contains four integers ai, bi, ci, di (0 ≤ ai, bi, ci, di ≤ 109) — the characteristics of the corresponding card.
In the first line print a single integer k — the minimum number of moves needed to cast the n-th spell and in the second line print knumbers — the indices of the cards in the order in which you should cast them. In case there are multiple possible solutions, print any of them.
If it is impossible to cast the n-th spell, print - 1.
4
0 0 3 4
2 2 5 3
4 1 1 7
5 3 8 8
3
1 2 4
2
0 0 4 6
5 1 1000000000 1000000000
-1
题意:给出n对点(ai,bi)、(ci, di),一开始在(0, 0),每一步可以从当前点(x, y)可以跳到(ci, di),条件是x>=ai且y>=bi。
问跳到(cn, dn)最少要多少步(这n对点是编号的,题目要求一定要跳到第n对点),要求方案。
分析:简单的BFS。
看似每次转移都要n次枚举,但是显然根据BFS的性质,每个点只可能转移一次。
转移之后删掉即可。
通过一定的链表之类的东西,按照x,y分别排序,然后在按照一定顺序扫描点,可以保证复杂度在O(n)
1 /** 2 Create By yzx - stupidboy 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cmath> 8 #include <deque> 9 #include <vector> 10 #include <queue> 11 #include <iostream> 12 #include <algorithm> 13 #include <map> 14 #include <set> 15 #include <ctime> 16 #include <iomanip> 17 using namespace std; 18 typedef long long LL; 19 typedef double DB; 20 #define MIT (2147483647) 21 #define INF (1000000001) 22 #define MLL (1000000000000000001LL) 23 #define sz(x) ((int) (x).size()) 24 #define clr(x, y) memset(x, y, sizeof(x)) 25 #define puf push_front 26 #define pub push_back 27 #define pof pop_front 28 #define pob pop_back 29 #define mk make_pair 30 31 inline int Getint() 32 { 33 int Ret = 0; 34 char Ch = ' '; 35 bool Flag = 0; 36 while(!(Ch >= '0' && Ch <= '9')) 37 { 38 if(Ch == '-') Flag ^= 1; 39 Ch = getchar(); 40 } 41 while(Ch >= '0' && Ch <= '9') 42 { 43 Ret = Ret * 10 + Ch - '0'; 44 Ch = getchar(); 45 } 46 return Flag ? -Ret : Ret; 47 } 48 49 const int N = 100010; 50 struct DataType 51 { 52 int sx, sy, ex, ey, index; 53 inline void Read() 54 { 55 scanf("%d%d%d%d", &sx, &sy, &ex, &ey); 56 } 57 } arr[N]; 58 struct StoreType 59 { 60 int key, index; 61 StoreType() {} 62 StoreType(int _key, int _index) 63 { 64 key = _key, index = _index; 65 } 66 inline bool operator <(const StoreType &t) const 67 { 68 return key < t.key; 69 } 70 } ; 71 vector<StoreType> store[N * 4]; 72 int n; 73 int m, next[N * 4]; 74 int dp[N], from[N], que[N]; 75 int ans, start; 76 77 inline void Input() 78 { 79 scanf("%d", &n); 80 for(int i = 0; i < n; i++) 81 { 82 arr[i].Read(); 83 arr[i].index = i; 84 } 85 } 86 87 inline void Relabel(DataType *data, int n, int &m) 88 { 89 static int arr[N * 4], len; 90 #define GetIndex(x) (lower_bound(arr, arr + len, x) - arr) 91 len = 0; 92 for(int i = 0; i < n; i++) 93 { 94 arr[len++] = data[i].sx; 95 arr[len++] = data[i].sy; 96 arr[len++] = data[i].ex; 97 arr[len++] = data[i].ey; 98 } 99 arr[len++] = 0; 100 sort(arr, arr + len); 101 len = unique(arr, arr + len) - arr; 102 for(int i = 0; i < n; i++) 103 { 104 data[i].sx = GetIndex(data[i].sx); 105 data[i].sy = GetIndex(data[i].sy); 106 data[i].ex = GetIndex(data[i].ex); 107 data[i].ey = GetIndex(data[i].ey); 108 } 109 m = len; 110 } 111 112 inline int Find(int x) 113 { 114 static int path[N * 4]; 115 int len = 0; 116 for(; next[x] != x; x = next[x]) path[len++] = x; 117 for(int i = 0; i < len; i++) 118 next[path[i]] = x; 119 return x; 120 } 121 122 inline void Bfs() 123 { 124 int head = 0, tail = 0; 125 que[tail++] = n - 1; 126 dp[n - 1] = 1, from[n - 1] = n; 127 start = -1; 128 while(head < tail) 129 { 130 int idx = que[head++]; 131 int x = arr[idx].sx, y = arr[idx].sy; 132 if(!x && !y) 133 { 134 start = idx; 135 return; 136 } 137 for(int tab = Find(x); tab < m; tab = Find(tab + 1)) 138 { 139 while(!store[tab].empty() && store[tab].back().key >= y) 140 { 141 int idy = store[tab].back().index; 142 que[tail++] = idy; 143 dp[idy] = dp[idx] + 1, from[idy] = idx; 144 store[tab].pob(); 145 if(store[tab].empty()) next[tab] = tab + 1; 146 } 147 } 148 } 149 } 150 151 inline void Solve() 152 { 153 Relabel(arr, n, m); 154 // printf("relabel"); 155 156 for(int i = 0; i < n - 1; i++) 157 store[arr[i].ex].pub(StoreType(arr[i].ey, i)); 158 for(int i = 0; i < m; i++) 159 if(store[i].empty()) next[i] = i + 1; 160 else 161 { 162 next[i] = i; 163 sort(store[i].begin(), store[i].end()); 164 } 165 next[m] = m; 166 // printf("initiazation"); 167 168 Bfs(); 169 // printf("bfs"); 170 171 if(start == -1) 172 { 173 puts("-1"); 174 return; 175 } 176 printf("%d\n", dp[start]); 177 vector<int> ans; 178 for(int x = start; x < n; x = from[x]) ans.pub(x); 179 printf("%d", ans.front() + 1); 180 for(int i = 1; i < dp[start]; i++) printf(" %d", ans[i] + 1); 181 puts(""); 182 } 183 184 int main() 185 { 186 freopen("a.in", "r", stdin); 187 Input(); 188 Solve(); 189 return 0; 190 }