CodeForces[102082] Emergency Evacuation

題目

解說

大體題意:給出列數、兩邊行數和人數,求把全部人挪出來須要的時間。一個位置上一次只能存在一我的。數組

若是沒有人和人之間的相互阻礙的話這道題極其簡單,因此如今的主要問題就落在瞭如何處理人擋人的問題。ide

什麼狀況下會出現人擋人呢?顯然是兩我的到出口的時間同樣的時候。spa

因爲這個結論可能沒那麼顯然,因此下面給一個通俗的證實解說。code

好比畫圈的兩我的在沒人遮擋時出去的時間是同樣的,兩人到最後確定都要通過出口前的一段路,這一段就是公共部分(藍色)。因爲兩人時間相等,所以刨去公共時間後的各自的時間(紅色和綠色)也是相等的,也就是說兩人在相等的時間後走到了重疊路段上,所以兩人必定相遇。這樣的話若是有兩我的的距離相等就說明須要等待,那麼咱們給第二我的的時間加1,給第三我的的時間加2,以此類推便可。blog

既然這樣事情就簡單了。把全部距離由小到大排序,以後按上面的方法操做便可。排序

而後就有了個人第一代代碼:it

(下面展現核心部分)io

1 for(int i=1;i<=p;i++){
2         if(a[i]==a[i-1]) k[i]=k[i-1]+1;
3         a[i]+=k[i];
4         ans=max(ans,a[i]);
5     }

而後就WA了。event

(啊啊啊不可能我這麼可貴地進行了這麼嚴謹的論證怎麼可能出錯???大腦在顫抖!!!)class

哪裏出問題了呢?

仔細想一下會發現上面的代碼沒有考慮排在前面的時間增長後對後面的影響。設想一種狀況:因爲咱們已經從小到大排了序,那麼正常狀況下前一個數小於等於後一個,但因爲時間增長,前一個數有可能變得比後一個大,這種狀況是什麼意思?就是一個原本排在你前面的人因爲延時時間變得比後面長了,也就是說後面的人被前面的堵住了,而且前面的人堵多長時間後面的就要陪它堵多長時間,由於後面的過不去啊。因此說咱們在遍歷數組時應判斷前面的數是否大於等於後面的,如果,就把後面的數改成前面的數加1。

代碼

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath> 
 4 using namespace std;
 5 const int maxn=500000+5;
 6 int a[maxn];
 7 int main(){
 8     int r,s,p;
 9     scanf("%d%d%d",&r,&s,&p);
10     for(int i=1;i<=p;i++){
11         int x,y;
12         scanf("%d%d",&x,&y);
13         if(y>s) a[i]=r-x+1+y-s;
14         else a[i]=r-x+1+s-y+1;
15     }
16     sort(a+1,a+1+p);
17     int ans=-1;
18     for(int i=1;i<=p;i++){
19         ans=max(ans,a[i]);
20         if(a[i]>=a[i+1]) a[i+1]=a[i]+1;
21     }
22     printf("%d",ans);
23     return 0;
24 }
View Code

 

幸甚至哉,歌以詠志。

相關文章
相關標籤/搜索