Description
小Q最近沉迷于一款新型《打砖块》游戏。在每局游戏中,呈现在屏幕上的是一堵无限大小的墙壁。墙壁上镶嵌着
无数长度为2、宽度为1的砖块。墙壁被分成若干行,每行宽度都为1,相邻两个格子形成一个砖块。相邻两行的砖
块是间隔摆放的。墙壁从下往上行编号递增,从左往右列编号递增。如下图所示:
![](http://begin.lydsy.com/JudgeOnline/upload/2285.png)
在游戏的一开始,有n块砖块消失了。如果两块在同一行且相邻的砖块都消失了,那么玩家可以移除它们上方与它
们都相邻的那一个砖块。请写一个程序帮助小Q计算最多可以让多少个位置没有砖块。
Input
第一行包含两个正整数n(1<=n<=100000),表示一开始消失的砖块个数。
接下来n行,每行两个整数x_i,y_i(|x_i|,|y_i|<=10^9)
分别表示每个消失的砖块的位置,即左半部分位于第x_i行第y_i列。
Output
输出一行一个整数,即没有砖块的位置个数的最大值。
Sample Input
7
0 0
0 2
2 0
3 1
1 3
3 5
0 6
0 0
0 2
2 0
3 1
1 3
3 5
0 6
Sample Output
9
用优先队列来维护这些砖块的顺序,对于同一行的数,维护一段连续砖块的左右区间。
//
// main.cpp
// bzoj5045
//
// Created by zc on 2017/10/17.
// Copyright © 2017年 zc. All rights reserved.
//
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define ll long long
#define max(a,b) ((a)>(b))?(a):(b)
using namespace std;
int n;
struct node
{
ll x, y1, y2;
friend bool operator < (const node &a,const node &b)
{
if(a.x!=b.x) return a.x > b.x;
else if(a.y1!=b.y1) return a.y1 > b.y1;
else return a.y2 < b.y2;
}
};
priority_queue<node> q;
template <class T>
bool read(T &ret)
{
char c;
int sgn;
T bit = 0.1;
if (c=getchar(), c==EOF)
{
return 0;
}
while (c != '-' && c != '.' && (c < '0' || c > '9'))
{
c = getchar();
}
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0' && c <= '9')
{
ret = ret * 10 + (c - '0');
}
if (c == ' ' || c == '\n')
{
ret *= sgn;
return 1;
}
while (c = getchar(), c >= '0' && c <= '9')
{
ret += (c - '0') * bit, bit /= 10;
}
ret *= sgn;
return 1;
}
int main(int argc, const char * argv[]) {
read(n);
while(!q.empty()) q.pop();
for(int i=0;i<n;i++)
{
ll x, y;
read(x);read(y);
node t;t.x=x;t.y1=t.y2=y;
q.push(t);
}
ll ans=0;
while(!q.empty())
{
node t=q.top();q.pop();
while(!q.empty())
{
node p=q.top();
if(t.x==p.x&&t.y2+2>=p.y1)
{
t.y2=max(t.y2,p.y2);
q.pop();
}
else break;
}
ans+=(t.y2-t.y1)/2+1;
node p;
p.x=t.x+1;p.y1=t.y1+1;p.y2=t.y2-1;
if(p.y1<=p.y2) q.push(p);
}
printf("%lld\n",ans);
}