Codeforces Round #643 (Div. 2)

Codeforces Round #643 (Div. 2)(2020.5.16)

这波啊,这波是加一百分。芜湖~

(但是依旧被队里大佬吊锤了%%%)

(比赛为了赶时间所以代码写得比较丑)

这场依旧还是奇奇怪怪的题目比较多。

A、Sequence with Digits

这题我一开始看确实一脸懵。还拿1的情况打了一张表。

发现1的情况是1,2,6,42,50,50,50,50…

后来仔细一想发现只要搜到出现0就可以停下来了,因为后面肯定都是一样的了。

然后就做完了。

#include 
using namespace std;
typedef long long ll;
int main()
{
    int t; cin >> t;
    while (t--)
    {
        ll a, k; cin >> a >> k;
        for (ll i = 2; i <= k; ++i)
        {
            ll temp = a, maxi = -1, mini = 999;
            while (temp)
            {
                int x = temp % 10; temp /= 10;
                if (x > maxi) maxi = x;
                if (x < mini) mini = x;
            }
            if (mini == 0) break;
            else a += maxi * mini;
        }
        cout << a << endl;
    }
    return 0;
}

B、Young Explorers

这题考虑一个贪心。先把数组排个序,然后肯定是把小的能分组的尽量单独分出来分组,最后剩下的一堆就不要管它了。虽然详细证明不太会,但是这么做感觉上肯定是对的。

#include 
using namespace std;
typedef long long ll;
const int MAXN = 2e5 + 10;
int main()
{
    int t; cin >> t;
    while (t--)
    {
        int n; cin >> n;
        vector <int> a(n + 1, 0);
        for (int i = 1; i <= n; ++i)
            scanf("%d", &a[i]);
        sort(a.begin() + 1, a.end());
        int ans = 0, now_cnt = 0;
        for (int i = 1; i <= n; ++i)
        {
            now_cnt++;
            if (now_cnt >= a[i]) ++ans, now_cnt = 0;
        }
        cout << ans << endl;
    }
    return 0;
}

C、Count Triangles

这题不懂为什么出的人比D少。个人感觉这题比D简单不少…

首先我们发现枚举 x , y x,y x,y肯定是会超的。但是发现组成三角形的条件是 x + y > z x+y>z x+y>z,那么我们可以考虑枚举 x + y x+y x+y,之后算出 x + y x+y x+y能组成多少种和为 m m m的情况,然后剩下的 z z z肯定是在 c c c m − 1 m-1 m1里选。最后两种情况乘起来累加就好了。

那么 z z z的范围其实不需要讨论,现在我们处理 x + y = m x+y=m x+y=m的个数问题。

其实这就是一个解不等式。把等式变个型, B ≤ y = m − x ≤ C B\le y=m-x\le C By=mxC,解出 m − C ≤ x ≤ m − B m-C\le x\le m-B mCxmB;又因为 A ≤ x ≤ B A\le x\le B AxB,然后我们取个交集就行了。之后右端点减左端点加一就是个数。

另外还有一点要注意就是 x x x或者 z z z的范围是空集的情况。比赛的时候没想那么多,因为反正枚举 m m m不会超时我就直接continue了。感觉直接break好像也对。

#include 
using namespace std;
typedef long long ll;
int main()
{
    ll a, b, c, d;
    cin >> a >> b >> c >> d;
    ll ans = 0;
    for (ll i = a + b; i <= b + c; ++i)
    {
        ll delta1 = (min(d, i - 1) - c + 1), delta2 = min(i - b, b) - max(i - c, a) + 1;
        if (delta1 < 0 || delta2 < 0) continue;
        else ans += delta1 * delta2;
    }
    cout << ans << endl;
    return 0;
}

D、Game With Array

这题卡了我很久。具体方法是取 k = 1 k=1 k=1,然后每次都填2就行了。如果最后两个元素的差大于1就直接输出NO。

但是至于这个方法为什么是对的我就很懵,莫名其妙就过了。

只能说我只知道取 k = 1 k=1 k=1然后填2这个方法是可以构造出一组解的,因为一旦首项填了2之后后面的和最多就只有 S − 2 S-2 S2,所以肯定不成立。之后只要保证相邻不为1就行了,所以加2。但为什么没有数据能把这个方法卡掉,或者说这个方法为什么对于所有数据都成立我就不知道了。总之很迷。

#include 
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 10;
int main()
{
    int n ,s; cin >> n >> s;
    int k = 1;
    static int sum[MAXN] = {0};
    sum[n] = s;
    for (int i = 1; i <= n - 1; ++i)
        sum[i] = sum[i - 1] + 2;
    if (sum[n - 1] + 2 <= sum[n])
    {
        cout << "YES" << endl;
        for (int i = 1; i <= n; ++i)
            cout << sum[i] - sum[i - 1] << ' ';
        cout << endl;
        cout << k << endl;
    }
    else cout << "NO" << endl;
    return 0;
}

E是个三分。我做完D之后还剩10分钟左右,E大概看了一下没想到有什么好的解决方法。零基础大哥光速解决D之后又秒了E,赛后问他怎么做,原话是:“盲猜对高度三分就过了。”

啊这。

你可能感兴趣的:(Codeforces Round #643 (Div. 2))