Codeforces Round #353 (Div. 2)C. Money Transfers

链接:http://codeforces.com/contest/675/problem/C

题意:给定和为0的n个数a[1]~a[n],形成环即a[1]与a[n]相邻,操作:每个位置的数能向它相邻的位置转移。求最后变成全0最少需要转移多少次。

分析:这题在比赛的时候卡了很多人,这个建模思想在大白书前两页就有,稍微有一点点变形,没看过的同学试着看看我写的分析吧。我们设第i的位置a[i]向它前面那个位置转移了xi,显然每个位置最多转移1次即答案<=n,且最后的值为0,所以我们能得到n个等式:a[i]-x[i]+x[i+1]=0。这有什么用呢?我们将这些等式变形得:x[1]=x[1],a[1]-x[1]+x[2]=0-->x[2]=x[1]-a[1],a[2]-x[2]+x[3]=0-->x[3]=x[2]-a[2]=x[1]-a[1]-a[2],x[4]=x[1]-a[1]-a[2]-a[3]。。x[n]=x[1]-a[1]-a[2]-a[3]...-a[n-1]。我们令c[i]=a[1]+a[2]+..+a[i-1]。那么有x[1]=x[1]-c[1],x[2]=x[1]-c[2],x[3]=x[1]-c[3]。。。x[n]=x[1]-c[n]。当我们得到了这n个等式之后我们考虑一下题目要我们求什么,未变动的位置最多即x[i]=0的位置最多。那么我们只要令x[1]为c数组的众数就好啦。详见代码。

代码:

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<bitset>
#include<math.h>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int N=100010;
const int MAX=1000000100;
const int mod=100000000;
const int MOD1=1000000007;
const int MOD2=1000000009;
const double EPS=0.00000001;
typedef long long ll;
const ll MOD=998244353;
const int INF=1000000010;
typedef double db;
typedef unsigned long long ull;
int g[N];
ll a[N],f[N];
int main()
{
    int i,n,ans=INF;
    scanf("%d", &n);
    for (i=1;i<=n;i++) scanf("%I64d", &a[i]);
    for (i=2;i<=n;i++) f[i]=f[i-1]+a[i];
    sort(f+1,f+n+1);
    g[1]=1;
    for (i=2;i<=n;i++)
    if (f[i]==f[i-1]) g[i]=g[i-1]+1;
    else g[i]=1;
    for (i=1;i<=n;i++) ans=min(ans,n-g[i]);
    printf("%d\n", ans);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值