codeforces 56E 多米诺骨牌效应
生活随笔
收集整理的這篇文章主要介紹了
codeforces 56E 多米诺骨牌效应
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
BSNY正在玩多米諾骨牌,他將n塊多米諾骨牌從左到右排成一行。其中每塊多米諾骨牌所在的位置設為x,每塊多米諾骨牌高度為h。如果將x位置上的多米諾骨牌向右翻到,它就可以影響[x+1, x+h-1]范圍內的所有多米諾骨牌,讓他們也翻到,同時這些被翻到的多米諾骨牌還能影響到其他多米諾骨牌,也就是多米諾骨牌效應。
例如現在有4塊多米諾骨牌,位置從左到右依次為10 16 18 20,它們的高度依次為10, 5, 2, 5。當翻到16位置上的多米諾骨牌,18和20位置都在范圍[16+1, 16+5-1],所以這兩塊也翻到了,總共翻到了3塊。
現在BSNY給出n塊多米諾骨牌的位置和高度,問如果向右翻到第i塊多米諾骨牌,會有多少多米諾骨牌翻到。
輸入
第一行輸入n
接下來n行每行輸入xi和hi,分別表示第i塊多米諾骨牌的位置和高度
輸出
輸出一行包含n個結果,用空格隔開
第i個結果表示如果向右翻到第i塊多米諾骨牌,會有多少多米諾骨牌翻到。
樣例輸入
4
16 5
20 5
10 10
18 2
樣例輸出
3 1 4 1
提示
【樣例說明】
輸入:
4
0 10
1 5
9 10
15 10
輸出:
4 1 2 1
【數據規模和約定】
例如現在有4塊多米諾骨牌,位置從左到右依次為10 16 18 20,它們的高度依次為10, 5, 2, 5。當翻到16位置上的多米諾骨牌,18和20位置都在范圍[16+1, 16+5-1],所以這兩塊也翻到了,總共翻到了3塊。
現在BSNY給出n塊多米諾骨牌的位置和高度,問如果向右翻到第i塊多米諾骨牌,會有多少多米諾骨牌翻到。
輸入
第一行輸入n
接下來n行每行輸入xi和hi,分別表示第i塊多米諾骨牌的位置和高度
輸出
輸出一行包含n個結果,用空格隔開
第i個結果表示如果向右翻到第i塊多米諾骨牌,會有多少多米諾骨牌翻到。
樣例輸入
4
16 5
20 5
10 10
18 2
樣例輸出
3 1 4 1
提示
【樣例說明】
輸入:
4
0 10
1 5
9 10
15 10
輸出:
4 1 2 1
【數據規模和約定】
1<=n<=10^5, ?-10^8<=xi<=10^8 , ?2<=hi<=10^8 ? xi都不一樣
********************************************************************
solution:相信大家都會n^2的暴力,但這無疑會超時。現在我們的一個瓶頸是:怎么快速計算?那么勢必要成片累加。我們可以記錄下每個點往后能夠連續推倒的數量,只要它在范圍內,就可以累加這個值,然后直接跳過已被覆蓋的點。這樣就可以大大節約時間(雖然仍有一部分常數),考試的時候我也是想到這種邊擴展邊累加的方法,但是沒想到用dp的方式來記錄并累加,所以就超了。。。。。
#include<cstdio> #include<iostream> #include<algorithm> #define p1 id<<1 #define p2 id<<1^1 using namespace std; int n; int ans[100005]; int tree[450000]; struct ty {int x,h,id,to; }d[100005]; bool cmp(ty a,ty b) {return a.x<b.x; } int main() {cin>>n;for(int i=1;i<=n;i++){scanf("%d%d",&d[i].x,&d[i].h);d[i].id=i;d[i].to=d[i].x+d[i].h-1;}sort(d+1,d+n+1,cmp);ans[d[n].id]=1;for(int i=n-1;i>=1;i--) {int last=d[i].to;int q=i+1;ans[d[i].id]=1;while(0==0){if(q>n) break;if(d[q].x<=last) ans[d[i].id]+=ans[d[q].id]; //為什么不用更新last,因為我在當前點能到的范圍之外的點,要是能推倒的話,肯定已經包括在當前范圍里的某個點中else break;q=q+ans[d[q].id];}} for(int i=1;i<n;i++) cout<<ans[i]<<' ';cout<<ans[n]<<endl;return 0; }
總結
以上是生活随笔為你收集整理的codeforces 56E 多米诺骨牌效应的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爬虫实战:12306登录
- 下一篇: Spark 数据ETL