Codeforces Round #642 (Div. 3)

题目传送门

A. Most Unstable Array

构造长度为n的序列,满足Σai=m,使∑|ai-ai+1|最大。

看样例也很好明白,像 0,0,...0,m,0,...,0,0这种一定是最大值为m*2

特判一下n==1,2就行了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)
 
ll n, m;
 
void solve()
{
    cin >> n >> m;
    if (n == 1)
        cout << "0" << endl;
    else if (n == 2)
        cout << m << endl;
    else
        cout << m * 2 << endl;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
View Code

B. Two Arrays And Swaps

两个长度为n的数组,k次交换其中的值,求max(∑a)。

很明显就是将b中最大的k个数和a中最小的k个数互换,这样的a就是所求的答案

互换的前提是b中的值要比a的大,不然不是最优。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)
 
ll n, k;
ll a[100], ans;
bool cmp(ll a, ll b) { return a > b; }
void solve()
{
    cin >> n >> k;
    ans = 0;
    rep(i, 1, 2 * n) cin >> a[i];
    sort(a + 1, a + n + 1, cmp);
    sort(a + n - k + 1, a + 2 * n + 1, cmp);
    rep(i, 1, n) ans += a[i];
    cout << ans << endl;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
View Code

C. Board Moves

将n*n的每个方格中的数字移至一个方格中,求最小移动数。

n为奇数,不难发现移到中心点为最优,

答案就是sum(max(mid-i,mid-j),i,j∈(1,n))

如果遍历每一个点,On*2是不行的,

然后发现从中心点出来每一圈的步数都是递增的,实际上就是计算每一圈的格子数乘当前的步数

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)
 
ll n;
ll ans;
void solve()
{
    cin >> n;
    ans = 0;
    rep(i, 1, n / 2) ans += 1ll * i * i * 8;
    cout << ans << endl;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
View Code

D. Constructing the Array

一个全零序列,每次操作选择最长靠左的子段[l,r],将a[(l+r)/2]赋值,然后分成2个子段,求最终序列。

用优先队列维护段长度,模拟即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for (register int i = a; i <= b; i++)

struct paii
{
    int first, second;
    bool operator<(const paii &a) const
    {
        if (second - first != a.second - a.first)
            return second - first < a.second - a.first;
        return first > a.first;
    }
};

ll n;
priority_queue<paii> q;
ll ans[200010];
void solve()
{
    cin >> n;
    q.push((paii){1, n});
    int i = 1;
    while (!q.empty())
    {
        paii tmp = q.top();
        int mid = (tmp.first + tmp.second) / 2;
        q.pop();
        ans[mid] = i++;
        if (mid > tmp.first)
            q.push((paii){tmp.first, mid - 1});
        if (mid < tmp.second)
            q.push((paii){mid + 1, tmp.second});
    }
    rep(i, 1, n) cout << ans[i] << " ";
    cout << endl;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}
View Code
原文地址:https://www.cnblogs.com/likunhong/p/12892703.html