Problem 2163 多米诺骨牌
Accept: 17 Submit: 50
Time Limit: 1000 mSec Memory Limit : 32768 KB
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
单调栈,如此神奇,呵呵...
这类题做少了
1 #include<iostream> 2 #include<stdio.h> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<stack> 7 using namespace std; 8 typedef __int64 LL; 9 10 struct node 11 { 12 LL x; 13 int h; 14 int id; 15 int i; 16 }f[100002]; 17 int ans[100002]; 18 19 20 bool cmp(node n1,node n2) 21 { 22 return n1.x<n2.x; 23 } 24 void solve(int n) 25 { 26 int i; 27 node k; 28 stack<node>Q; 29 Q.push(f[1]); 30 31 for(i=2;i<=n;i++){ 32 while( !Q.empty() && (Q.top().x+Q.top().h-1) <f[i].x) 33 { 34 k=Q.top(); 35 Q.pop(); 36 ans[k.i]=f[i].id-k.id; 37 } 38 Q.push(f[i]); 39 } 40 } 41 int main() 42 { 43 int n,i; 44 while(scanf("%d",&n)>0) 45 { 46 for(i=1;i<=n;i++) 47 { 48 scanf("%I64d%d",&f[i].x,&f[i].h); 49 f[i].i=i; 50 } 51 n++; 52 f[n].x=(1<<30); 53 sort(f+1,f+1+n,cmp); 54 for(i=1;i<=n;i++) 55 { 56 f[i].id=i; 57 } 58 solve(n); 59 for(i=1;i<n;i++) 60 { 61 if(i!=1)printf(" "); 62 printf("%d",ans[i]); 63 } 64 printf(" "); 65 } 66 return 0; 67 }