uva11300 + uvalive5809 中位数
来源:互联网 发布:有线网络电视怎么连接 编辑:程序博客网 时间:2024/06/09 20:07
uva11300 的基本思想是利用中位数的性质
x1表示的是第一个人需要给第四个人多少金币
x2表示的是第二个人需要给第一个人多少金币
x3表示的是第三个人需要给第一个人多少金币
.....
xn-1表示的是第n-1个人需要给第一个人多少金币
对于一开始每个人的金币数用Ai表示
M表示最终每个人得到的金币数 M = 金币总数 / 总人数
对于第一个人A1 - x1 + x2 = M - A1 + x1 = x1 - C1
对于第一个人A2 - x2 + x3 = M - A2 + x2 = x1 - C2
对于第一个人A3 - x3 + x4 = M - A3 + x3 = x1 - C3
其中 Cn = (A1 + A2 + …… + An) - n*M = An + C(n-1) - M
要求最小的交换次数 就转换为了 求 |x1| + |x1 - C1| + |x2 - C2| + …… + |x1 - C(n-1)|
几何意义就是数轴上的点C1、C2、C3、……、C(n-1) 到x1点的距离的最小值
有中位数的一个性质:在给定的数轴上的 n 个点, 在数轴上的所有点中, 中位数离所有顶点的距离之和最小。( 证明略 )
下面给出代码:
#include<cstdio>#include<algorithm>#include<iostream>using namespace std;const int maxn = 1000000+10;long long a[maxn], c[maxn], tot, m;int main(){ int n; while(scanf("%d",&n) == 1) { tot = 0; for(int i = 1; i <= n; i++) { scanf("%lld",&a[i]); tot += a[i]; } m = tot / n; //确定最终每个人得到的金币的数量 c[0] = 0; for(int i = 0; i < n; i++) c[i] = c[i-1] + a[i] - m; sort(c, c + n); long long x1 = c[n/2]; //求出c[n]数组中的中位数 long long ans = 0; for(int i = 0; i < n; i++) ans += abs(x1 - c[i]); printf("%lld\n",ans); } return 0;}
题目要求输出行和列需要经过增氧的变换 可以使行列之和相等
换句话说 如果把行列数先求出来 对于行数 单独按照上一题的思路进行变换
对于列数 单独按照上一题的思路进行变换
最后统计一下 行列交换的结果 就行
代码如下 写的有些乱 不太好看懂
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int maxn = 1000+10;long long a[maxn], c[maxn], tot, m;int yuanshi[maxn][maxn];char shuru[maxn][maxn];int change(int a[], int n){ tot = 0; for(int i = 1; i <= n; i++) tot += a[i]; if(tot % n != 0) return -1; //一定不会交换成功 m = tot / n; //确定最终每个人得到的金币的数量 c[0] = 0; for(int i = 0; i < n; i++) c[i] = c[i-1] + a[i] - m; sort(c, c + n); long long x1 = c[n/2]; //求出c[n]数组中的中位数 long long ans = 0; for(int i = 0; i < n; i++) ans += abs(x1 - c[i]); return ans; //成功}int main(){ int n; int time1; int row1,column1; int rowjieguo, columnjieguo; int row[maxn],column[maxn]; scanf("%d\n",&time1); for(int i = 1; i <= time1; i++) { memset(shuru, '\0', sizeof(shuru)); memset(yuanshi, 0, sizeof(yuanshi)); scanf("%d%d",&row1,&column1); for(int i1 = 1; i1 <= row1; i1++) scanf("%s",shuru[i1]); //输入 for(int i1 = 1; i1 <= row1; i1++) { for(int j1 = 1; j1 <= column1; j1++) yuanshi[i1][j1] = (int)shuru[i1][j1-1]-30-18; } //对输入的结果进行转换 memset(row, 0, sizeof(row)); memset(column, 0, sizeof(column)); rowjieguo = columnjieguo = 0; //初始化 for(int i1 = 1; i1 <= row1; i1++) { for(int j1 = 1; j1 <= column1; j1++) row[i1] += yuanshi[i1][j1]; } rowjieguo = change(row, row1); for(int j1 = 1; j1 <= column1; j1++) { for(int i1 = 1; i1 <= row1; i1++) column[j1] += yuanshi[i1][j1]; } columnjieguo = change(column, column1); //结果输出 if(rowjieguo == -1 && columnjieguo == -1) printf("Case %d: impossible\n",i); if(rowjieguo == -1 && columnjieguo != -1) printf("Case %d: column %d\n",i, columnjieguo); if(rowjieguo != -1 && columnjieguo == -1) printf("Case %d: row %d\n",i, rowjieguo); if(rowjieguo != -1 && columnjieguo != -1) printf("Case %d: both %d\n",i, rowjieguo+columnjieguo); } return 0;}
- uva11300 + uvalive5809 中位数
- 中位数uva11300
- uva11300-中位数
- uva11300 - Spreading the Wealth (中位数)
- UVA11300 Spreading the Wealth (数学推导+中位数)
- UVa11300
- uva11300
- uva11300
- UVa11300
- UVa11300
- UVa11300
- UVA 10137(截取精度)和UVA11300(中位数)
- 中位数
- 中位数
- 中位数
- 中位数
- 中位数
- 中位数
- Longest Substring Without Repeating Characters —— Leetcode
- POJ 1258 Agri-Net
- android adb install + apk 与adb push+apk两种安装apk的使用总结
- apache与iis共用80端口
- 寻找丢失的数
- uva11300 + uvalive5809 中位数
- NEUQ 1213: 半数集问题
- JAVA基础篇七(Java,C++中的线程)
- ubuntu下怎样版本号和内核版本号
- Andrew Ng机器学习-Linear Regression with one variable
- hdu2669与hdu1576(扩展欧几里德)
- 递归:阶乘以及菲波那切数列的程序实现
- PHP下载、安装
- Opencv交叉编译到ARM(基于Qt)