多米诺骨牌

Problem Description
Vasya很喜欢排多米诺骨牌。他已经厌倦了普通的多米诺骨牌,所以他用不同高度的多米诺骨牌。他从左边到右边,把n个多米诺骨牌沿一个轴放在桌子上。每一个多米诺骨牌垂直于该轴,使该轴穿过其底部的中心。第i个多米诺骨牌具有坐标xi与高度hi。现在Vasya想要知道,对于每一个多米诺骨牌如果他推倒的话,右侧会有多少个多米诺骨牌也会倒下。
想想看,一个多米诺倒下,如果它严格的触动右侧的多米诺骨牌,被触碰的也会倒下。换句话说,如果多米诺骨牌(初始坐标x和高度h)倒下,会导致所有在[ X + 1,x + H - 1]范围内的多米诺骨牌倒下。
Input
输入有多组测试数据,处理到文件结尾。
每组测试数据第一行包含整数n(1≤N≤10^5),这是多米诺骨牌的数量。然后n行,每行包含两个整数xi与hi(-10^8≤xi≤10^8 ,2 ≤hi≤108),xi表示多米诺骨牌的坐标和hi表示多米诺骨牌的高度。没有两个多米诺骨牌在同一个坐标点上。
Output
对于每组数据输出一行,包含n个空格分隔的数Zi - 表示倒下的多米诺骨牌数量,如果Vasya推第i个多米诺骨牌(包括多米诺骨牌本身)。
Sample Input
4
16 5
20 5
10 10
18 2
3
6 7
2 9
-6 10
Sample Output
3 1 4 1
1 2 3
//关键字:栈的运用。
//标程:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
using namespace std;
const int c = 100010;
struct node
{
	__int64 x;
	int h;
	int len;
	int i;
}p[c];
int dp[c];
bool cmp(node nd1,node nd2)
{
	return nd1.x < nd2.x;
}
void fun(int n)
{
	node nd;
	stack<node> st;
	st.push(p[1]);
	for(int i = 2; i <= n; i ++)
	{
		while(!st.empty() && (st.top().x + st.top().h -1) < p[i].x)
		{
			nd = st.top();
			st.pop();
			dp[nd.i] = p[i].len - nd.len;
		}
		st.push(p[i]);
	}
}
int main()
{
// 	freopen("a.txt","r",stdin);
        int n, i, j;
	while(scanf("%d",&n)!=EOF)
	{
		for(i = 1; i <= n; i ++)
		{
			scanf("%I64d%d",&p[i].x,&p[i].h);
		    p[i].i = i;
		}
                n ++;
		p[n].x = (1 << 30);
		sort(p+1,p+1+n,cmp);
		for(i = 1; i <= n; i ++)
			p[i].len = i;
		fun(n);
		for(i = 1; i < n; i ++)
		{
			if(i != 1) printf(" ");
			printf("%d",dp[i]);
		}
		printf("\n");
	}
	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值