原题
思路:这道题目思路和糖果传递思路类似,下面写出糖果传递题目糖果传递
有n个小朋友坐成一圈,每人有a[i]个糖果。
每人只能给左右两人传递糖果。
每人每次传递一个糖果代价为1。
求使所有人获得均等糖果的最小代价。
输入格式
第一行输入一个正整数n,表示小朋友的个数。
接下来n行,每行一个整数a[i],表示第i个小朋友初始得到的糖果的颗数。
输出格式
输出一个整数,表示最小代价。
数据范围
1≤n≤1000000
数据保证一定有解。
输入样例:
4
1
2
5
4
输出样例:
4
思路:
1.分析题意
1->2->3->4->...->n->1 构成一个环
x1 x2 x3 x4 .... xn xi表示xi给xi+1糖果的个数,xi可正可负可为零。
本题要求|x1|+|x2|+|x3|+.....+|xn|的最小值。
限制条件:最后每个人获得均等糖果。
av表示平均值,a数组表示每个人初始糖果的数量。
2.列出式子
Xn - X1 + a1 = avg
x1 - x2 + a2 = avg
....
Xn-1 - Xn + an = avg
3.推导出
x2 = x1 - (avg - a2)
x3 = x2 -(avg - a3)
.....
xn = Xn-1 - (avg - an)
4.规律
x2 = x1 - c2 (c2 = c1 + avg -a2)
x3 = x1 - c3 (c3 = c2 + avg - a3)
...
xn = Xn-1 - cn (cn = Cn-1 + avg - an)
5.问题转化
|x1 - c1| + |x2 - c2| +...+|xn - cn|
转化为货仓选址问题
结论 :我们首先把所有坐标排个序然后找出中位数即可如果是奇数
个,那中位数就是最中间的。如果是偶数个,那中位数在最中间的两
个之间,取这两个的任意一个都是答案(因为是整形嘛)
6.糖果传递代码
#include<iostream>
#include<algorithm>
#include<cmath>
const int N = 1e6 + 10;
int a[N];
int c[N];
int n;
using namespace std;
int main()
{
int i = 0;
long long sum = 0;
cin>>n;
for(i = 1;i <= n;i++)
{
scanf("%d",&a[i]);
sum += a[i];
}
int avg = sum/n;
for(i = 2;i <= n;i++)
{
c[i] = c[i-1] + avg -a[i];
}
sort(c+1,c+n+1);
long long coun = 0;
int k = 1 + n >>1;
for(i = 1;i <= n;i++)
{
coun += abs(c[k] - c[i]);
}
cout<<coun<<endl;
return 0;
}
7.七夕祭代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
int n,m,t;
int x[N];
int y[N];
int row[N];
int column[N];
long long c[N];
int main()
{
cin>>n>>m>>t;
for(int i = 1;i <= t;i++)
{
scanf("%d",&x[i]);
scanf("%d",&y[i]);
row[x[i]]++;
column[y[i]]++;
}
if((t % n !=0) && (t % m != 0))
{
printf("impossible\n");
}
else if(t % n != 0)
{
int avg = t/m;
for(int i = 2;i<=m;i++)
{
c[i] = c[i-1] + avg -column[i];
}
sort(c+1,c+m+1);
long long coun = 0;
int k = 1 + m >>1;
for(int i = 1;i <= m;i++)
{
coun += abs(c[k] - c[i]);
}
cout<<"column "<<coun<<endl;
}
else if(t %m != 0)
{
int avg = t/n;
for(int i = 2;i<=n;i++)
{
c[i] = c[i-1] + avg -row[i];
}
sort(c+1,c+n+1);
long long coun = 0;
int k = 1 + n >>1;
for(int i = 1;i <= n;i++)
{
coun += abs(c[k] - c[i]);
}
cout<<"row "<<coun<<endl;
}
else
{
int avg = t/m;
for(int i = 2;i<=m;i++)
{
c[i] = c[i-1] + avg -column[i];
}
sort(c+1,c+m+1);
long long coun1 = 0;
int k = 1 + m >>1;
for(int i = 1;i <= m;i++)
{
coun1 += abs(c[k] - c[i]);
}
for(int i = 1;i<=m;i++)
{
c[i] = 0;
}
avg = t/n;
for(int i = 2;i<=n;i++)
{
c[i] = c[i-1] + avg -row[i];
}
sort(c+1,c+n+1);
long long coun2 = 0;
k = 1 + n >>1;
for(int i = 1;i <= n;i++)
{
coun1 += abs(c[k] - c[i]);
}
long long coun = coun1 + coun2;
cout<<"both "<<coun<<endl;
}
return 0;
}