【CodeForces - 675C】Money Transfers(思维,前缀和)
題干:
There are?n?banks in the city where Vasya lives, they are located in a circle, such that any two banks are neighbouring if their indices differ by no more than?1. Also, bank?1?and bank?n?are neighbours if?n?>?1. No bank is a neighbour of itself.
Vasya has an account in each bank. Its balance may be negative, meaning Vasya owes some money to this bank.
There is only one type of operations available: transfer some amount of money from any bank to account in any?neighbouring?bank. There are no restrictions on the size of the sum being transferred or balance requirements to perform this operation.
Vasya doesn't like to deal with large numbers, so he asks you to determine the minimum number of operations required to change the balance of each bank account to zero. It's guaranteed, that this is possible to achieve, that is, the total balance of Vasya in all banks is equal to zero.
Input
The first line of the input contains a single integer?n?(1?≤?n?≤?100?000)?— the number of banks.
The second line contains?n?integers?ai?(?-?109?≤?ai?≤?109), the?i-th of them is equal to the initial balance of the account in the?i-th bank. It's guaranteed that the sum of all?ai?is equal to?0.
Output
Print the minimum number of operations required to change balance in each bank to zero.
Examples
Input
3 5 0 -5Output
1Input
4 -1 0 1 0Output
2Input
4 1 2 3 -6Output
3Note
In the first sample, Vasya may transfer?5?from the first bank to the third.
In the second sample, Vasya may first transfer?1?from the third bank to the second, and then?1?from the second to the first.
In the third sample, the following sequence provides the optimal answer:
題目大意:
有n家銀行,構成了一個環,每個銀行都有余額,有的為正數,有的是負數,但是總的余額是0,定義一次操作:相鄰的銀行之間可以轉任意數目的錢。求把所有的銀行的余額都轉為0的所需最少操作次數。
解題報告:
剛開始是想的以0為分界線,后來發現好像不太行。參考題解
當有一小段(長度為len)的總和為0時, 我們可以用len-1步來使這一小段使這一小段全部變成0,
考慮將n個銀行分成k小段, 由于是環型結構并且總和為0, 不會存在最后湊不成總和為0的一小段的情況.
k小段的長度分別是len1,len2,.....lenk, 所需要的步數分別是len1-1,len2-1,....lenk-1,??len1+len2+...+lenk
是等于n的, 然后k個-1, 最后就是n-k, 要使n-k最小, k要盡量大. 就是要把n個數分成盡量多的段數.
考慮前綴和, 統計不同前綴和的個數, 相同的前綴和之間夾的一小段數肯定是總和為0的, 用不同的前綴和
劃分這n個數k可能不同, 我們統計這些前綴和并且取最大的.
AC代碼:
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<stack> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define FF first #define SS second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<int,int> PII; const int MAX = 2e5 + 5; map<ll,ll> mp; int n; ll x,ans,sum; int main() {cin>>n;for(int i = 1; i<=n; i++) {cin>>x;sum += x;mp[sum]++;ans = max(ans,mp[sum]);}cout << n-ans << endl;return 0 ; }?
總結
以上是生活随笔為你收集整理的【CodeForces - 675C】Money Transfers(思维,前缀和)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 暴雨黄色预警!14个省份有大到暴雨 可能
- 下一篇: spyagent4.exe - spya