題意:
現在有n個城市圍成一個環,每個城市有ai個家庭需要供電,並且每個城市有一個發電廠,可以供給第i和第i+1個城市共bi個家庭的電。問你每個家庭是否都能得到電。
題解:
那麼我們首先選擇一個i,要求是bi>=ai。
那麼我們假設bi首先滿足ai,然後多的供給給下一個城市,這樣做一遍,很明顯中間會有不夠的地方,此時我們就需要讓選擇的這個起始城市多供給給缺的部分。
那麼假設所有缺的加起來爲mx,如果mx>ai的話,bi就算將bi全部都傳遞過去也不夠,所以這種情況不行。
如果mx<=ai,那麼就表示有戲,我們就讓bi少傳遞mx給ai,將mx的電傳遞到下一個。那麼此時bi傳遞給ai的電就是ai-mx,於是ai就還需要mx格電,此時我們設傳遞的電的數量爲bi-ai+mx,將ai置爲mx,bi置爲0.
然後再做一遍,如果不行就是真的不行,中間一定有斷點使得bi的電傳不過去。
時間複雜度應該是的,但是可能常數太大導致花了700ms左右,時間複雜度應該可以優化,但沒必要。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+5;
ll a[N],b[N];
int n;
int main()
{
int t;
scanf("%d",&t);
for(int tim=1;tim<=t;tim++){
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lld",&a[i]);
int sta=-1;
for(int i=0;i<n;i++)
scanf("%lld",&b[i]),sta=b[i]>=a[i]?i:sta;
if(sta==-1){
printf("NO\n");
continue;
}
ll res=0,mx=0;
for(int i=sta;i<=sta+n-1;i++){
int u=i%n;
if(b[u]+res>=a[u])
res=min(b[u],res+b[u]-a[u]);
else
mx+=a[u]-b[u]-res,res=0;
}
if(mx){
if(mx>a[sta]){
printf("NO\n");
continue;
}
res=b[sta]-a[sta]+mx;
a[sta]=mx;
b[sta]=0;
mx=0;
for(int i=sta+1;i<=sta+n;i++){
int u=i%n;
if(b[u]+res>=a[u])
res=min(b[u],res+b[u]-a[u]);
else{
mx=1;
break;
}
}
if(mx)
printf("NO\n");
else
printf("YES\n");
}
else
printf("YES\n");
}
return 0;
}