ural 1251. Cemetery Manager
2015-12-26 10:40
519 查看
1251. Cemetery Manager
Time limit: 1.0 secondMemory limit: 64 MB
There is a tradition at the USU championships to call the most hard-to-solve problems coffins. But to distribute coffins is also a very difficult problem. Consider a cemetery with places arranged in the form of a rectangle having N rows and M columns (1 ≤ N, M ≤ 100). At the initial moment of time (t = 0) the cemetery is empty. Incoming coffins are put in the row with empty places that has a minimal number; if there are several empty spaces in this row, then the column with the minimal number is chosen. From time to time the cemetery's clients are visited by their living friends and relatives; it is considered to be a pleasure for the clients. But it's only a headache for the cemetery manager, since because of these visitors he cannot give to new clients places that have been used. Happily, visitors are not perfect, so after some time they forget where their friends have been lying. That is why if a client was not visited for more than successive 1000 days, then on the 1001st day the manager regards the grave as empty. However, relatives of the adjacent clients (of those for whom the differences in the numbers of rows and columns are not greater than 1) may notice strange changes, so the manager puts a new client on a used place only if all the neighboring graves have not been visited for the last 100 days (this is a period of time sufficient for a neighbor's friends to forget who was lying next to him or her). If, notwithstanding all the efforts of the manager, there is no place where he can put a new client, then the client is sent to a crematorium.
We have a complete list of arriving clients and coming visitors for some period starting from the foundation of the cemetery. Basing on this information, you should determine how many clients have been sent to a crematorium.
Input
The first input line contains numbers N and M that describe the size of the cemetery. Each of the next lines describes an event. A description starts with the time of the event measured in days from the foundation of the cemetery. Then the type of the event is given: either d (arrival of a new client) or v (a visit of friends or relatives) followed with the number of the client who has visitors. The events are ordered according to their time. The input contains not more than 15000 events, and not more than 10000 of them describe arrivals of new clients.Output
The program should find the number of clients that have been sent to a crematorium.Sample
input | output |
---|---|
2 2 1 d 1 d 1 d 1 d 300 d 500 v 2 1001 d 1002 d 1002 d 1003 v 3 1003 d 1003 d 1236 v 2 2032 v 2 2033 d | 3 |
Notes
Each tomb has 2 to 8 neighbors.If a client was buried on day T then the tomb may be dug over on day T+1001 and may not be dug over on day T+1000.
If a tomb was visited on day T then its neighbors may be dug over on day T+101 and may not be dug over on day T+100.
A tomb is dug over as soon as there is an opportunity (see items 2 and 3).
During a funeral relatives notice nothing including the neighbors.
The clients are numbered in the the order that they arrive (including those who was sent to crematorium).
If there is already no tomb or the client has been sent to the crematorium immediately or there is no client with the required number then a visit affects nothing.
The next in turn client may be always burried in an empty tomb inspite of the neighbor tombs visits (the neighbors' relatives wouldn't be surprised having found out that the adjacent empty tomb is already occupied).
Problem Author: Stanislav Vasilyev
Problem Source: Open collegiate programming contest for student teams, Ural State University, March 15, 2003
Tags: data structures (hide tags for unsolved problems)
Difficulty: 1522
题意:自己看题吧。比较复杂,注意看题后面的tips。
分析:可以用两个优先队列搞一下就可以了。
一个维护当前的空墓地,按照x,y的顺序存进优先队列。
一个维护当前墓地的有效时间(即即将被铲掉的时间)。
如果这个有效时间被修改,其实可以打个标记什么的,将新时间扔进优先队列,不需要删除原来那个。这题并不会爆空间。
这题比较麻烦,居然能够1A。也是蛮幸运的。
/** 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 = 110, MAXINDEX = 15010, LEN = 1000, ILEN = 100; class Node { private : int x, y; public : Node() {} Node(int tx, int ty) { x = tx, y = ty; } inline bool operator <(const Node &t) const { if(x != t.x) return x > t.x; return y > t.y; } inline int GetRow() { return x; } inline int GetCol() { return y; } inline int GetTime() { return x; } inline int GetIndex() { return y; } } ; class Heap { private : priority_queue<Node> Store; public : inline void Push(int x, int y) { Store.push(Node(x, y)); } inline void Push(const Node &x) { Store.push(x); } inline void Pop() { Store.pop(); } inline Node GetTop() { return Store.top(); } inline bool Empty() { return Store.empty(); } } deadtime, emptylist; int n, m, cnttombs; int endtime[MAXINDEX], graph ; Node where[MAXINDEX]; bool have[MAXINDEX]; int ans; inline void Input() { scanf("%d%d", &n, &m); } inline void Dug(int now) { while(!deadtime.Empty()) { Node t = deadtime.GetTop(); int idx = t.GetIndex(), deadline = t.GetTime(); if(!have[idx] || endtime[idx] != deadline) deadtime.Pop(); else if(deadline >= now) break; else { emptylist.Push(where[idx]); graph[where[idx].GetRow()][where[idx].GetCol()] = -1; where[idx] = Node(-1, -1); endtime[idx] = -1, have[idx] = 0; deadtime.Pop(); } } } inline bool AddTomb(int now) { bool ret = 0; cnttombs++; while(!ret && !emptylist.Empty()) { Node t = emptylist.GetTop(); int x = t.GetRow(), y = t.GetCol(); graph[x][y] = cnttombs, where[cnttombs] = t; have[cnttombs] = 1, endtime[cnttombs] = now + LEN; deadtime.Push(endtime[cnttombs], cnttombs); emptylist.Pop(); ret = 1; } return ret; } inline bool Check(int x, int y) { if(x < 0 || x >= n || y < 0 || y >= m) return 0; if(!graph[x][y] || !have[graph[x][y]]) return 0; return 1; } inline void Visit(int now, int idx) { const int DX[] = {-1, 0, 1, 0, -1, -1, 1, 1}, DY[] = {0, -1, 0, 1, -1, 1, -1, 1}; if(!have[idx]) return; int x = where[idx].GetRow(), y = where[idx].GetCol(); endtime[idx] = max(endtime[idx], now + LEN); deadtime.Push(endtime[idx], idx); for(int t = 0; t < 8; ++ t) { int dx = x + DX[t], dy = y + DY[t]; if(!Check(dx, dy)) continue; endtime[graph[dx][dy]] = max(endtime[graph[dx][dy]], now + ILEN); deadtime.Push(endtime[graph[dx][dy]], graph[dx][dy]); } } inline void Solve() { for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) emptylist.Push(i, j); char type; int t, idx; while(scanf("%d", &t) == 1) { for(type = ' '; type != 'v' && type != 'd'; type = getchar()); Dug(t); if(type == 'd') { bool ret = AddTomb(t); ans += !ret; } else { scanf("%d", &idx); Visit(t, idx); } } printf("%d\n", ans); } int main() { freopen("a.in", "r", stdin); Input(); Solve(); return 0; }
View Code
相关文章推荐
- spring项目加入jta分布式事务的实现方式: Atomikos
- mycncart 之网银在线chinapay支付方式
- web网站服务2
- mysql函数大全
- HDOJ 1003 在本地编译是正确的,请大神看看我的程序错在哪里
- RNSS与RDSS的集成
- URI|URL|URN
- Hexo搭建Github静态博客
- mysql 查询数据库的表名 列名
- TCP IP详解(转)
- mycncart 之 SEO KeyWord的集中管理功能及改进seo url
- Mysql允许IP访问的设置
- iOS开发面试题整理
- ural 1250. Sea Burial
- ural 1250. Sea Burial
- gzip: stdin:unexpected end of file
- SpringMVC框架总体介绍(一)
- junit之verify方法
- CSAPP Data Lab
- mycncart操作使用教程 - 横幅广告