【ZOJ4054】2018ICPC青島賽區網路賽H Traveling on the Axis(字首和)
阿新 • • 發佈:2019-02-17
【題意】
在[0,n]中每0.5處設定一個紅綠燈,0表示紅燈,1表示綠燈,如果在4.5處有紅燈,要從4到5,就要等1s,給出初始的紅綠燈狀態,每1s會改變狀態,即由紅燈變成綠燈,或綠燈變成紅燈,然後計算圖中表達式。
【解題思路】
可以手動模擬一下第3個例子
1 1 0 1 0
從0:1 3 4 5 6
從1: 1 2 3 4
從2: 2 3 4
從3: 1 2
從4: 2
很容易可以發現當上一個燈的狀態和下一個燈相同時,則需要2s才能通過,反之只需要1s,用f[i]記錄需要通過的時間。
i*(n-i+1)*f[i]表示f[i]在所有答案中出現的次數,若s[i-1]=0時,說明初始時需要再等1s,所以之後的答案都需要加上n-i+1,如果f[i]=2,那麼以i開始的區間的答案需要減去n-i+1。
【程式碼】
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=1e5+5; char s[maxn]; LL f[maxn]; int main() { int T; scanf("%d",&T); while(T--) { memset(s,0,sizeof(s)); memset(f,0,sizeof(f)); scanf("%s",s); LL n=strlen(s),ans=0; f[1]=1; for(LL i=1;i<n;i++) { if(s[i]==s[i-1])f[i+1]=2; else f[i+1]=1; } for(LL i=1;i<=n;i++) { ans+=i*(n-i+1)*f[i]; if(s[i-1]=='0')ans+=n-i+1; if(f[i]==2)ans-=n-i+1; } printf("%lld\n",ans); } return 0; }