codeforces 675c[补]

比赛的时候都去看c题了。。就没看这题。。赛后看了下,随便听了下他们的题意,没注意到成环,然后就随意yy模拟跑一遍,结果第一组样例没跑过的时候才知道是成环,之后还有队友说,用map过了,很懵,这题跟map有半毛钱关系。。。直到后来终于想通。。

题目:http://codeforces.com/problemset/problem/675/C
题目大意:貌似有一个金库那样的东西,可以存ai的钱,然后其他地方有ai的钱,整个成环的街道的钱总和为0,现在问最少多少步可以让整个街道的钱每个位置都为0,存的钱ai为负数,其他地方的钱为正数。

其实不难发现,总共要走的步数为n - 成0的最大区域数。
于是可以想到统计前缀和来判断到底有多少个成0区域。
因为如果某两段的前缀和想同,说明那两段的差值一定为0,那两段一定有成0的区间,然后整个地区成环,那么保证了一定有一条长度为n的0区间,所以只需要统计前缀和每一个数出现的次数,减去最大的次数即为所需走的步数。
但是数的数量只有100000,而数的大小为-1e9 到 1e9,所以用map可以轻松的储存每一个数所出现的次数(orz原来这就是用map的原因。。)

代码如下:

/*
@resouces: codeforces
@date: 2017-3-17
@author: QuanQqqqq
@algorithm: 
*/

#include <bits/stdc++.h>

#define ll long long 
#define MAXN 100005
using namespace std;

map<ll,int> mapp;
int main(){
    int n;
    scanf("%d",&n);
    int ans = n;
    ll sum = 0,a;
    for(int i = 0;i < n;i++){
        scanf("%lld",&a);
        sum += a;
        mapp[sum]++;
        ans = min(ans,n - mapp[sum]);
    }
    printf("%d\n",ans);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值