您的位置:首页 > 其它

ural 1251. Cemetery Manager

2015-12-26 10:40 519 查看

1251. Cemetery Manager

Time limit: 1.0 second
Memory 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

inputoutput
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: