【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- 10^9 ≤ ai ≤ 10910^9), 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
inputCopy
3
5 0 -5
outputCopy
1
inputCopy
4
-1 0 1 0
outputCopy
2
inputCopy
4
1 2 3 -6
outputCopy
3

Note
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:
transfer 1 from the first bank to the second bank;
transfer 3 from the second bank to the third;
transfer 6 from the third bank to the fourth.

思路:

總結下題意,你在n家銀行有存款(正數)或借款(負數)xix_i,現在需要把所有賬單做平,你的存款剛好可以還上所有借款,但是錢只能在相鄰的兩家銀行間流通(因爲銀行位於一個圈內,所以第1家和第n家間也可以流通),求最少操作次數(保證有解)。
一個長度爲len區間內,如果區間和爲0,則最多操作len-1次就能使所有數變爲0,然後問題就變成了有多少個這樣的區間了。

設共有有ans個區間,每個區間長度爲aia_i
則總操作次數爲i=1ansaians\sum_{i=1}^{ans}{a_i} - ans
又因爲i=1ansai\sum_{i=1}^{ans}{a_i}即總長度n,
所以i=1ansaians=nans\sum_{i=1}^{ans}{a_i} - ans=n-ans
然後就是如何快速求出有多少個區間和爲0的區間了。

然後考慮前綴和前綴和,如何兩個數的前綴和相同,即sumi=sunjsum_i=sun_j,則[i,j]區間內存在一個區間和爲0的區間,這樣我們就只需要找最好有多少個數的前綴和相同了。

例1:1 2 3 -6
前綴和 1 3 6 0
區間個數:1
答案:3
例2:1 2 3 -6 3 -6 6
前綴和 1 3 6 0 3 -3 3
區間個數:3
答案:4

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;
ll x[110000];
map<ll,int> m;


int main()
{
	int n;
	ll t;
	int ans=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&t);
		x[i]=x[i-1]+t;
		m[x[i]]++;
		ans=max(ans,m[x[i]]);
	}
	printf("%d\n",n-ans);
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章