来源:牛客网
题目描述
输入描述:
第一行一个整数T(T<=100),表示组数
对于每组数据有一个n,表示序列的长度(0< n <100000)
下面一行有n个数,表示每个序列的值(0<ai<1000)
输出描述:
输出两个数 第一个数表示最小的操作步数 第二个数经过若干步以后的数组元素是什么
代码:
强迫症的序列
根据题意,由于每次操作,都给n-1 个元素都加
1,所以为了使得所有的序列都达到一样的值,
要想操作步数最小,
那么你每步操作都一定要对最小值加一,那么有
这样的前提下,你可以做出如下推论
step: 总操作步数
ans:最终序列的元素
min:序列里的最小值
n:序列长度
可以看出,最终的值等于最小值加上操作步数:
ans = min + step
终态序列的求和与初始序列的求和有如下关系:
n ∗ ans − Σai = step ∗ (n − 1)
联立求解得
n ∗ min + n ∗ step − Σai = step ∗ (n − 1)
n ∗ min + n ∗ step − Σai = n ∗ step − n
step = Σai − n ∗ min
step = Σ(ai − min)
为什么每步一定要给最小值加一(瞎证)
假设给最小值操作了步,有step2 步没有操作最
小值
step: 总操作步数
step1: 含最小值的操作数
step2: 不含最小值的操作数
ans:最终序列的元素
min:序列里的最小值
n:序列长度
step = step1 + step2
因为加step1 次,就不操作min,说明他达到了
最终状态,所以ans 值有下列关系
ans = mi + step1
n ∗ ans − Σai = step ∗ (n − 1)
∗ + ∗ − Σ = ( + ) ∗ ( − 1)
n ∗ min + n ∗ step1 − Σai = (step1 + step2)
∗ (n − 1)
step1 − (n − 1) ∗ step2 = Σ(ai − min)
上面的等式,右边大于零,所以右边也要大于零
step1 > (n − 1) ∗ step2
这样你就会发现step2 的操作其实是多余的,大
致就是这样吧
2.减到最小值的步数就是把他们加到一样数的步数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include<iostream>
using
namespace
std;
int
main()
{
int
n,t;
cin>>t;
int
a[100000];
while
(t--)
{
cin>>n;
long
long
int
sum=0;
int
min=100000;
for
(
int
i=0;i<n;i++)
{
cin>>a[i];sum+=a[i];
if
(a[i]<min)
min=a[i];
}
cout<<sum-n*min<<
" "
<<min+(sum-n*min)<<endl;
}
}
|