前方数学警告

题目链接:https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=25&page=show_problem&problem=2275

https://www.luogu.com.cn/problem/UVA11300

分析:

搞了这么久终于碰到一个数学题了,这也是本蒟蒻做的第一个数学题吧,值得纪念。

第一次看见这题的时候,嗯,好像是个暴力。。。然后就打了一个暴力,发现样例过了?但自己造了组数据就有了点问题,我暴力的思路是由于一个人只能给左边或右边,于是把这两种情况都枚举一下,取最小值就好,但有可能跑一遍不能让整个数组都变成我想要的那个值,故我又加了一个bool表示有无把所有数字都变成那个数,这么写肯定T啊。

我:万一数据水呢?

数据:我不水。

所以交上去果断T掉了,我又想验证一下这么写可不可以,找某人代码过来对拍了一下,然后结果是我竟然把一个A掉的代码给拍出了错解?嗯,看来写个暴力还是有收获的,我其实很想把那个代码粘上来的,但它88行有点长我没存不小心弄丢了,来看一下正解吧。

首先我最开始发现的那个性质是没有问题的,即每个人只会被它周围的人影响,一旦他周围的人的转移硬币数确定了,那么这个人的转移硬币数也可求,于是受这一点启发,不妨设\(x_i\)表示第\(i\)个人给第\(i-1\)个人的硬币数,当\(i==1\)时,为给\(n\)的硬币数。由于最后要求所有人金币一样(共产主义),所以最后每个人的金币数量是确定的,即\(M=tot/n\),也就是说每个人最后都是\(M\),于是有\(A_i+x_{i+1}-x_i=M\),就是原来有的加上得到的减去失去的等于最终的,光看这个式子,这啥也看不出来啊,所以继续观察这个式子,发现它跟周围的式子相加会出现一个神奇的结果,我们加一下看看。

\(A_1+x_2-x_1=M\) 1

\(A_2+x_3-x_2=M\) 2

\(A_3+x_4-x_2=M\) 3

1+2得\(A_1+A_2+x_3-x_1=M*2\) -> \(x_3=x_1-(A_1+A_2-M*2)\)

1+2+3得\(x_4=x_1-(A_1+A_2+A_3-M*3)\)

………………

不难归纳得出\(x_n=x_1-\)\(\sum_{i=1}^n(A_{i-1}+(i-1)*M\)\()\)

有这个式子我们就可以很简单困难的求出答案了,设\(B_i=\)\(\sum_{i=1}^n(A_{i-1}+(i-1)*M\),\(B\)数组可以由递推得到,那么问题就简化成了在数组\(B\)中求一个数,使得剩余数到它的距离之和最小,答案是中位数,证明如下。



假设\(a_1,a_2,a_3,a_4,a_5\)有序,则\(a_3\)是中位数无疑,我们用线段来表示点与点之间的距离,可以看出蓝色框框内的线段是必不可少的,不管怎么划分都必须要有,如果这个点在\(a_3\)的左边,那么就会多出粉色的一截,在右边就会多出红色的一截,所以在中位数时是最小的。

那偶数呢?偶数不是有两个中位数吗?偶数时也画出一个这样的图,会发现当点在两个中位数之间距离都是一样的,并且是最小,所以为了方便,每次中位数都取\(n+1>>1\)就可以了。

中位数怎么找呢,排序一遍可以,但复杂度是\(O(nlogn)\)的,如果要使数组有序,那么肯定是要\(sort\)的,这里只求中位数,所以可以用\(nth\)\(element\),这个函数的用法是\(nth\)\(element(A+a,b,A+c)\),表示将数组A的区间\([a,c)\)中第b大的数放在b位置上,不保证数组有序,但比这个数大的都在它前边,比它小的在它后边,平均时间复杂度\(O(n)\)。

#include<iostream>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e6+10;
ll a[N],b[N];
int main(){
ios::sync_with_stdio(false);
int n;
while(cin>>n){
ll tot=0;
for(int i=1;i<=n;i++)
cin>>a[i],tot+=a[i],b[i]=0;
tot/=n;
for(int i=2;i<=n;i++)
b[i]=b[i-1]+a[i]-tot;
int mid=n+1>>1;
nth_element(b+1,b+mid,b+n+1);
ll temp=b[mid],res=0;
for(int i=1;i<=n;i++)
res+=abs(temp-b[i]);
cout<<res<<'\n';
}
}

tips:cout<<endl的确比cout<<'\n'慢一点。

UVA11300 Spreading the Wealth 数学的更多相关文章

  1. Uva11300 Spreading the Wealth

    设第i个人需要给第i+1个人的金币数为xi(xi为负代表收到钱),列出一大堆方程. 设第i个人给第i-1个人的钱为xi(xi<0表示第i-1个人给第i个人钱).计算出最后每个人应该有的钱m,解方 ...

  2. 【题解】 UVa11300 Spreading the Wealth

    题目大意 圆桌旁边坐着\(n\)个人,每个人有一定数量的金币,金币的总数能被\(n\)整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数量相等.您的任务是求出被转手的金币的数量的最小值. ...

  3. UVA11300 Spreading the Wealth 题解

    题目 A Communist regime is trying to redistribute wealth in a village. They have have decided to sit e ...

  4. (洛谷P2512||bzoj1045) [HAOI2008]糖果传递 || 洛谷P4016 负载平衡问题 || UVA11300 Spreading the Wealth || (洛谷P3156||bzoj3293) [CQOI2011]分金币

    bzoj1045 洛谷P4016 洛谷P2512 bzoj3293 洛谷P3156 题解:https://www.luogu.org/blog/LittleRewriter/solution-p251 ...

  5. UVA 11300 Spreading the Wealth (数学推导 中位数)

    Spreading the Wealth Problem A Communist regime is trying to redistribute wealth in a village. They ...

  6. 数学/思维 UVA 11300 Spreading the Wealth

    题目传送门 /* 假设x1为1号给n号的金币数(逆时针),下面类似 a[1] - x1 + x2 = m(平均数) 得x2 = x1 + m - a[1] = x1 - c1; //规定c1 = a[ ...

  7. Uva 11300 Spreading the Wealth(递推,中位数)

    Spreading the Wealth Problem A Communist regime is trying to redistribute wealth in a village. They ...

  8. Math - Uva 11300 Spreading the Wealth

    Spreading the Wealth Problem's Link ---------------------------------------------------------------- ...

  9. UVa 11300 Spreading the Wealth(有钱同使)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New ...

随机推荐

  1. JAVAEE学习day04方法的定义和重载

    1.方法定义的格式 方法就是完成特定功能的代码块 修饰符 返回值类型 方法名(参数类型 参数名1, 参数类型 参数名2...){ 方法体; return 返回值; } 修饰符: 初学者只需记住publ ...

  2. React 的 PureComponent Vs Component

    一.它们几乎完全相同,但是PureComponent通过prop和state的浅比较来实现shouldComponentUpdate,某些情况下可以用PureComponent提升性能 1.所谓浅比较 ...

  3. 使用form 表单 弹出登录框,只传递数据,不刷新界面

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 【JAVA进阶架构师指南】之一:如何进行架构设计

    前言   本博客是长篇系列博客,旨在帮助想提升自己,突破技术瓶颈,但又苦于不知道如何进行系统学习从而提升自己的童鞋.笔者假设读者具有3-5年开发经验,java基础扎实,想突破自己的技术瓶颈,成为一位优 ...

  5. 【TIJ4】照例,每个分类的第一篇文章随便说两句

    [其实没啥好说的,完].... 嘛,其实本来也就是放练习的地方. 如果说世界上的课本按练习难度分成两类,一类是像Weiss那种习题比内容难的,还有就是TIJ这种讲得详尽但是习题相对简单的了吧. 不过不 ...

  6. AspNetCore3.1_Secutiry源码解析_4_Authentication_JwtBear

    title: "AspNetCore3.1_Secutiry源码解析_4_Authentication_JwtBear" date: 2020-03-22T16:29:29+08: ...

  7. angualrjs 总结 随记(一)

    $apply方法的作用 $apply方法是用来触发脏检查,它在控制器里监听一个变量,每当这个变量的值改变的时候,它会去与最初的值做一次比较,然后HTML页面就会及时更新该变量的值(将最新的值赋值到ht ...

  8. MySQL学习(3)

    一 SQL语句 1. 数据库级别(*) 显示全部数据库:show databases; 创建数据库:create database '数据库名字’; 使用数据库:use '数据库名字'; 删除数据库: ...

  9. CBV和APIView源码分析

    CBV源码分析 查看源码的方式,先查看自身,没有去找父类,父类没有就去找父父类... 自己定义的类 class Author(View): def get(self,request): back_di ...

  10. Windows下利用Chrome调试IOS设备页面

    本文介绍如何在 Windows 系统中连接 iOS设备 并对 Web 页面进行真机调试 必须前提 iOS设备.数据线 Node.js 环境 Chrome 浏览器 环境准备 安装Node环境 参考Nod ...