1. 程式人生 > >小奇畫畫(對於容器的使用)

小奇畫畫(對於容器的使用)

小奇畫畫

時間限制: 1 Sec  記憶體限制: 128 MB

題目描述

紅蓮清淚兩行欲吐半點卻無
如初是你杳然若緋霧還在水榭畔畫樓處
是誰衣白衫如初誰紅裳如故
——《憶紅蓮》

小奇想畫幾朵紅蓮,可惜它剛開始學畫畫,只能從畫圓開始。小奇畫了n個圓,它們的圓心都在x軸上,且兩兩不相交(可以相切)。現在小奇想知道,它畫的圓把畫紙分割成了多少塊?(假設畫紙無限大)

 

輸入

第一行包括1個整數n。
接下來n行,每行兩個整數x,r,表示小奇畫了圓心在(x,0),半徑為r的一個圓。

 

輸出

輸出一個整數表示答案。

 

樣例輸入

複製樣例資料

4 
7 5 
-9 11 11 9 
0 20

樣例輸出

6

 

提示

對於 100%資料,1<=n<=300000,-10^9<=x<=10^9,1<=r<=10^9。

先將所有圓的區間和區間的距離算出來,根據左區間小,右區間大來排。然後遍歷一遍,因為沒有圓相交,所以後一個圓要麼在前一個圓外面,要麼就在前一個圓裡面,如果在裡面,記錄下大圓被小圓站了多少距離,如果大圓被小圓佔領的距離正好等於大圓的直徑,那麼就被分成兩份。

PS:有n個圓肯定至少把平面分為n+1部分。

/**/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>

typedef long long LL;
using namespace std;

int n, f[300005];

struct node
{
	int l, r, num;
	bool operator <(const node &x)const{
		return l == x.l ? r > x.r : l < x.l;
	}
}a[300005];

stack<int> st;

int main()
{
	//freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);

	scanf("%d", &n);
	int x, R;
	for (int i = 1; i <= n; i++){
		scanf("%d %d", &x, &R);
		a[i].l = x - R, a[i].r = x + R;
		a[i].num = 2 * R;
	}
	sort(a + 1, a + 1 + n);
	st.push(1);
	for (int i = 2; i <= n; i++){
		while(st.size() && a[st.top()].r < a[i].r) st.pop();
		if(st.size()) f[st.top()] += a[i].num;
		st.push(i);
	}
	int ans = n + 1;
	for (int i = 1; i <= n; i++){
		//cout << f[i] << endl;
		if(f[i] == a[i].num) ans++;
	}
	printf("%d\n", ans);

	return 0;
}
/**/