逆向思维题

链接:https://www.nowcoder.com/acm/contest/90/J
来源:牛客网

题目描述

牛客网是IT求职神器,提供海量C++、JAVA、前端等职业笔试题库,在线进行百度阿里腾讯网易等互联网名企笔试面试模拟考试练习,和牛人一起讨论经典试题,全面提升你的编程。作为acmer的小A,牛客网是他首选的题库。
小A是一个中度强迫症患者,每次做数组有关的题目都异常难受,他十分希望数组的每一个元素都一样大,这样子看起来才是最棒的,所以他决定通过一些操作把这个变成一个看起来不难受的数组,但他又想不要和之前的那个数组偏差那么大,所以他每次操作只给这个数组的其中n-1个元素加1,但是小A并不能很好的算出最优的解决方案,如果你能帮他解决这个问题,小A就能送你一个气球

输入描述:

第一行一个整数T(T<=100),表示组数

对于每组数据有一个n,表示序列的长度(0< n <100000)

下面一行有n个数,表示每个序列的值(0<ai<1000)

输出描述:

输出两个数
第一个数表示最小的操作步数
第二个数经过若干步以后的数组元素是什么
思路:n
#include <cstdio>
#include <cmath>
const int N = 1e5 + 10;
const int Inf = 0x3f3f3f3f;
int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || '9' < ch)
    {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while ('0' <= ch && ch <= '9')
    {
        x = x * 10 + ch - 48;
        ch = getchar();
    }
    return x * f;
}
 
int n, a[N];
void solve()
{
    int n = read(), min = Inf;
    for (int i = 1; i <= n; ++i)
        a[i] = read();
    for (int i = 1; i <= n; ++i)
        min = a[i] < min ? a[i] : min;
    long long s = 0;
    for (int i = 1; i <= n; ++i)
        s += a[i] - min;
    printf("%lld %lld\n", s, min + s);
}
int main()
{
    for (int T = read(); T; T--)
        solve();
    return 0;
}

-1个数+1等价于1个数-1所以只要将每个数减到和最小的数相同就可以(和最小值差值的和就是进行的操作数),最后正着推回去,因为最小值没有减过,所以最小值每一步都在加1,所以最后最小值加上操作数就是最终的数字。
展开阅读全文

没有更多推荐了,返回首页