A. Array Balancing

Code

void solve()
{
    cin >> n;
    for (int i = 1; i <= n; i++)	cin >> a[i];
    for (int i = 1; i <= n; i++)	cin >> b[i];
    
    int res = 0;
    for (int i = 1; i < n; i++)
        res += min(abs(a[i] - a[i + 1]) + abs(b[i] - b[i + 1]), abs(a[i] - b[i + 1]) + abs(b[i] - a[i + 1]))
    	
    cout << res << endl;
}

B. Getting Zero(位运算)

题目大意

解题思路

Code

void solve()
{   
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        int res = 0x3f3f3f3f;
        int x;  cin >> x;
        for (int i = 1; i <= 15; i++)
        {
            int t = ((1 << i) - 1) & x;  // 如从10000变为01111, &之后可以得到另一个数字的后四位大小
            int k;  //  +1的次数
            if (t == 0) k = 0;  // 特判,如果x本身就是0的话,不需要加1
            else k = (1 << i) - t;
            res = min(res, 15 - i + k);  //15 - i是*2的次数  *2 相当于左移一位
        }
        cout << res << ' ';
    }
}

C. Water the Trees (分类讨论)

题目大意

有若干棵树,奇数天可以浇水让一棵树长高$1$个单位,偶数天可以浇水让一棵树长高$2$个单位,问最少多少天可以让所有数长得一样高.

解题思路

假设我们已经知道了最终树要长多高,我们可以统计一下每棵树要长高的高度,我们发现要长高的高度为奇数的树至少需要一次在奇数天浇水,而要长高的高度为偶数的树无所谓.所以我们统计要长高的高度为奇数的树的数目$cnt$.出现$cnt$次奇数天最少需要$2 * cnt - 1$天.然后我们再统计以下一共需要长高的高度,计算需要的总天数和前面的值比较取大即可.

假设所有树初始高度中最大值为$maxv$,另外一个要注意的点是所有树最终高度的取值只有可能是$maxv$和$maxv + 1$,取$maxv + 1$有可能可以通过减少奇数天数的数量来降低答案,所以两个高度分别计算取小即可.

Code

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 300030;

int n, a[N];

int solve(int maxv)
{
    int sum = 0, cnt = 0;   // cnt表示奇数的数量
    for (int i = 1; i <= n; i++)
    {
        int d = maxv - a[i];
        sum += d;
        if (d & 1)  cnt++;
    }

    int res = 0;
    if (sum % 3 == 0)   res = max(2LL * cnt - 1, sum / 3 * 2);
    else if (sum % 3 == 1)  res = max(2LL * cnt - 1, sum / 3 * 2 + 1);
    else res = max(2LL * cnt - 1, sum / 3 * 2 + 2);  //  再等到一个偶数天需要先经过一个奇数天
    
    return res;
}

signed main()
{
    int t;  cin >> t;
    while (t--)
    {
        cin >> n;
        for (int i = 1; i <= n; i++)    cin >> a[i];
        int maxv = *max_element(a + 1, a + 1 + n);
        cout << min(solve(maxv), solve(maxv + 1)) << endl; // 不可能是(maxv+2)天,因为全体+2的操作可以被撤回
    }
}
上一篇 下一篇