CF#335 Board Game

Board Game
time limit per test
2.5 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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, aibici 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).

Input

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 aibicidi (0 ≤ ai, bi, ci, di ≤ 109) — the characteristics of the corresponding card.

Output

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.

Sample test(s)
input
4
0 0 3 4
2 2 5 3
4 1 1 7
5 3 8 8
output
3
1 2 4
input
2
0 0 4 6
5 1 1000000000 1000000000
output
-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 }
View Code

 

转载于:https://www.cnblogs.com/StupidBoy/p/5062558.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值