CF#335 Board Game
2015-12-21 09:53
281 查看
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, 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).
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 ai, bi, ci, di (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
output
input
output
题意:给出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)
View Code
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, 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).
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 ai, bi, ci, di (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)
/** Create By yzx - stupidboy */ #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <deque> #include <vector> #include <queue> #include <iostream> #include <algorithm> #include <map> #include <set> #include <ctime> #include <iomanip> using namespace std; typedef long long LL; typedef double DB; #define MIT (2147483647) #define INF (1000000001) #define MLL (1000000000000000001LL) #define sz(x) ((int) (x).size()) #define clr(x, y) memset(x, y, sizeof(x)) #define puf push_front #define pub push_back #define pof pop_front #define pob pop_back #define mk make_pair inline int Getint() { int Ret = 0; char Ch = ' '; bool Flag = 0; while(!(Ch >= '0' && Ch <= '9')) { if(Ch == '-') Flag ^= 1; Ch = getchar(); } while(Ch >= '0' && Ch <= '9') { Ret = Ret * 10 + Ch - '0'; Ch = getchar(); } return Flag ? -Ret : Ret; } const int N = 100010; struct DataType { int sx, sy, ex, ey, index; inline void Read() { scanf("%d%d%d%d", &sx, &sy, &ex, &ey); } } arr ; struct StoreType { int key, index; StoreType() {} StoreType(int _key, int _index) { key = _key, index = _index; } inline bool operator <(const StoreType &t) const { return key < t.key; } } ; vector<StoreType> store[N * 4]; int n; int m, next[N * 4]; int dp , from , que ; int ans, start; inline void Input() { scanf("%d", &n); for(int i = 0; i < n; i++) { arr[i].Read(); arr[i].index = i; } } inline void Relabel(DataType *data, int n, int &m) { static int arr[N * 4], len; #define GetIndex(x) (lower_bound(arr, arr + len, x) - arr) len = 0; for(int i = 0; i < n; i++) { arr[len++] = data[i].sx; arr[len++] = data[i].sy; arr[len++] = data[i].ex; arr[len++] = data[i].ey; } arr[len++] = 0; sort(arr, arr + len); len = unique(arr, arr + len) - arr; for(int i = 0; i < n; i++) { data[i].sx = GetIndex(data[i].sx); data[i].sy = GetIndex(data[i].sy); data[i].ex = GetIndex(data[i].ex); data[i].ey = GetIndex(data[i].ey); } m = len; } inline int Find(int x) { static int path[N * 4]; int len = 0; for(; next[x] != x; x = next[x]) path[len++] = x; for(int i = 0; i < len; i++) next[path[i]] = x; return x; } inline void Bfs() { int head = 0, tail = 0; que[tail++] = n - 1; dp[n - 1] = 1, from[n - 1] = n; start = -1; while(head < tail) { int idx = que[head++]; int x = arr[idx].sx, y = arr[idx].sy; if(!x && !y) { start = idx; return; } for(int tab = Find(x); tab < m; tab = Find(tab + 1)) { while(!store[tab].empty() && store[tab].back().key >= y) { int idy = store[tab].back().index; que[tail++] = idy; dp[idy] = dp[idx] + 1, from[idy] = idx; store[tab].pob(); if(store[tab].empty()) next[tab] = tab + 1; } } } } inline void Solve() { Relabel(arr, n, m); // printf("relabel"); for(int i = 0; i < n - 1; i++) store[arr[i].ex].pub(StoreType(arr[i].ey, i)); for(int i = 0; i < m; i++) if(store[i].empty()) next[i] = i + 1; else { next[i] = i; sort(store[i].begin(), store[i].end()); } next[m] = m; // printf("initiazation"); Bfs(); // printf("bfs"); if(start == -1) { puts("-1"); return; } printf("%d\n", dp[start]); vector<int> ans; for(int x = start; x < n; x = from[x]) ans.pub(x); printf("%d", ans.front() + 1); for(int i = 1; i < dp[start]; i++) printf(" %d", ans[i] + 1); puts(""); } int main() { freopen("a.in", "r", stdin); Input(); Solve(); return 0; }
View Code
相关文章推荐
- HTML5的发展趋势
- 采用API实现的文件拖放
- 去掉界面头
- 5种解决Java独占写文件的方法
- Java多线程——死锁
- 二维码扫描下载APP plist文件配置
- Oracle12cCDB和PDB数据库的启动与关闭说明
- Oracle12cCDB和PDB数据库的启动与关闭说明
- java内存溢出和tomcat内存配置
- 文件系统API的基本概念
- LeetCode Group Anagrams
- Spring JdbcTemplate框架搭建及其增删改查使用指南
- Android中dp和px之间进行转换
- 基本排序_直接插入排序_Java实现
- iOS 容易造成循环引用的三种场景
- 利用bak文件恢复数据库问题小结
- html5 自带表单验证怎么禁用
- hdu 5029 Relief grain(树链剖分+线段树)
- Vmware 安装 Arch Linux 2015
- 无法打开内核设备:\\Global\\vmx86