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

原题请戳这里

题意:

n个银行成环形排列。每个银行有一定的余额ai,每次可以在任意相邻的银行间转账。问

最少需要经过多少次转账使得所有银行的余额都为0.

分析:

由于所有银行的余额总数为0,则若把整个环看成一段,需要n-1次使所有余额为0。

把ai分为k个sum=0的部分,每部分的长度为li,使每个部分所有银行清零需要li-1步。n个

银行清零总共需要n-k步。

因此即是求(n-k)min,那么k值越大越好。

考虑前缀和,若sum[i]==sum[j],则区间[i+1,j]必定和为0,且[j+1,n]和[1,i]区间的sum也为0。

求出前缀和出现最多的次数,即是可以分成的最多的片段和为0的个数。

 1 #include<bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 typedef long long ll;
 6
 7 ll a[100005];
 8 map<ll,int> mp;
 9
10 int main()
11 {
12     int n;
13     while(~scanf("%d",&n))
14     {
15         mp.clear();
16         ll sum = 0;
17         int ans = n-1;
18         for(int i=0;i<n;i++)
19         {
20             scanf("%I64d",&a[i]);
21             sum += a[i];
22             mp[sum]++;
23             ans = min(ans,n-mp[sum]);
24         }
25         printf("%d\n",ans);
26     }
27     return 0;
28 }
时间: 2024-10-03 07:59:34

Codeforces Round #353 (Div. 2) C. Money Transfers (思维)的相关文章

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

题目大意:某个人在N个银行的存款和借款总和为0,这N个银行排成一个圆环,每次转账只能在相邻的两个银行之间进行.问进行多少次转账能使每个银行的存款为0. 题目保证总和一定是0. 有两个理论基础需要先说明. 一个总和为0的长度为N的区间内至多转账N-1次就可以使每个账户存款为0.因此只要找出总和为0的区间个个数最多设为W,那么答案就是N-W 一个区间总和为零的充要条件是,第一个元素之前的前缀和等于最后一个元素截止的前缀和. #include <iostream> #include <map&

Codeforces Round #353 (Div. 2) A. Infinite Sequence 思维题

A. Infinite Sequence time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Vasya likes everything infinite. Now he is studying the properties of a sequence s, such that its first element is equal

Codeforces Round #353 (Div. 2) ABCDE 题解 python

Problems # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring Painting standard input/output 1 s, 256 MB    x2519 C Money Transfers standard input/output 1 s, 256 MB    x724 D Tree Construction standard input/output 2

Codeforces Round #353 (Div. 2) D. Tree Construction (二分,stl_set)

题目链接:http://codeforces.com/problemset/problem/675/D 给你一个如题的二叉树,让你求出每个节点的父节点是多少. 用set来存储每个数,遍历到a[i]的时候查找比a[i]大的数的位置,然后插入,而父亲就是刚好比a[i]小的数或刚好大的数. 然后讨论是哪一个数. 比如给你3 1 2 ,如图 1的父亲是3 ,2的父亲是1. 那我其实只要找左边或右边出现最晚的数就行了,用pair的first表示a[i],second表示出现的顺序i. 1 #include

Codeforces Round #353 (Div. 2) D. Tree Construction (BST询问父亲节点)

原题请戳这里 题意: 给出n个不同的数,按照给出的顺序构造二叉排序树BST,第1个数为根节点.输出2-n个 节点的父亲节点. 分析: 二叉排序树的平均复杂度是log2n,最坏情况下变成线性的,复杂度为n. 对n个节点的插入操作如果用结构体指针的写法最坏情况下为n2=1010,这样会超时. 开始没有注意这点,TLE.但是正好复习了BST的插入操作递归和非递归的写法. 易知,插入的数的父亲节点是已插入的比它大或者比它小的与其最接近的数之一. 这个题利用set保存输入的数,用两个map分别记录左右孩子

Codeforces Round #353 (Div. 2)Restoring Painting

Vasya works as a watchman in the gallery. Unfortunately, one of the most expensive paintings was stolen while he was on duty. He doesn't want to be fired, so he has to quickly restore the painting. He remembers some facts about it. The painting is a

数据结构 - Codeforces Round #353 (Div. 2) D. Tree Construction

Tree Construction Problem's Link ---------------------------------------------------------------------------- Mean: 给定n个数,按照构造Binary Search Tree的方式来构造BST树,按顺序输出每一个非root结点的父节点的值. analyse: 构造BST树最坏情况下时间复杂度为O(n),肯定会超时. 注意到只需要输出结点的父节点的值,不需要真的构造BST树. 插到第i

[Codeforces] Round #353 (Div. 2)

A题题意:给出一个等差数列的首项和公差,求x是否是该数列中的项 1 #include<bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 int a,b,c; 5 scanf("%d%d%d",&a,&b,&c); 6 if(c>0&&b-a>=0&&(b-a)%c==0)printf("YES\n"); 7 else if(c&l

Codeforces Round #353 (Div. 2) A. Infinite Sequence

Vasya likes everything infinite. Now he is studying the properties of a sequence s, such that its first element is equal to a (s1 = a), and the difference between any two neighbouring elements is equal to c (si - si - 1 = c). In particular, Vasya won