1. 程式人生 > >zstu 4247-萌新的旅行

zstu 4247-萌新的旅行

新的 closed family space bits gif aps col lap

題目大意:

zstu的萌新們準備去自助旅行,他們租了一輛吉普車,然後選擇了n個城市作為遊覽地點。然後他們驚喜的發現他們選擇的城市剛好繞城一個環。

也就是說如果給所有城市按照0,1,2,……,n-1編號,0號城市和n-1號城市是相鄰的,並且只能從i號城市去(i+1)%n號城市。

已知每個城市可以充油gas(i),從 i 到 (i+1)%n 城市耗油 cost(i)。n<=1e5;

假設這輛吉普車沒有的油箱一開始是空的,並且沒有上限。

沒有油的話自然就不能繼續旅行了,這個問題讓萌新們非常困擾。作為優秀的acmer,請你幫他們找到一個出發城市,使得萌新們能遊覽盡可能多的城市(註意最多遊覽n個城市)。如果有多個可選擇的出發城市,那麽請把他們按照編號從小到大輸出。

思路:先將每個城市的充油減去去下一個城市的耗油,為了方便我們將數組擴展為兩倍。那麽問題就變成了

給你n個數字,任選一個a點為起點,這個起點能達到的最遠距離b,b是第一個滿足sum[b]-sum[a-1]<0,那麽

我們先求一個前綴和然後用單調棧就能解決問題了,時間復雜度O(n)。

ps:又忘了初始化,wa哭了。

技術分享圖片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=4e5+5;
 4 int a[N],n,ans[N],sum[N],r[N],tot,st[N];
 5 vector<int
> out; 6 void init() 7 { 8 out.clear(); 9 for(int i=1;i<=n;i++) ans[i]=n-1; 10 memset(sum,0,sizeof(sum)); 11 memset(r,0,sizeof(r)); 12 tot=0; 13 } 14 int main() 15 { 16 int T; scanf("%d",&T); 17 while(T--) 18 { 19 scanf("%d",&n); 20 init();
21 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 22 for(int i=1;i<=n;i++) 23 { 24 int g; scanf("%d",&g); 25 a[i]-=g; 26 a[i+n]=a[i]; 27 } 28 for(int i=1;i<=2*n;i++) sum[i]+=sum[i-1]+a[i]; 29 for(int i=2*n;i>=0;i--) 30 { 31 while(tot>0 && sum[st[tot-1]]>=sum[i]) tot--; 32 r[i]=tot==0 ? 2*n+1:st[tot-1]; 33 st[tot++]=i; 34 } 35 int mx=0; 36 for(int i=0;i<n;i++) ans[i+1]=min(ans[i+1],r[i]-i-1),mx=max(ans[i+1],mx); 37 for(int i=1;i<=n;i++) if(ans[i]==mx) out.push_back(i-1); 38 printf("%d",out[0]); 39 int len=out.size(); 40 for(int i=1;i<len;i++) printf(" %d",out[i]); 41 puts(""); 42 } 43 return 0; 44 }
View Code

zstu 4247-萌新的旅行