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

来源:互联网 发布:老挝 知乎 编辑:程序博客网 时间:2024/05/29 19:07

链接: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