Codeforces Round #643 (Div. 2)(A, B, C, D)

Codeforces Round #643 (Div. 2)

Sequence with Digits

思路

一道暴力题,猜想在某一步一定会出现0,于是怀着忐忑提交了代码,结果还真的是这样。

代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

ll judge(ll x) {
    int minn = x % 10, maxn = x % 10;
    ll temp = x;
    temp /= 10;
    while(temp) {
        minn = min(int(temp % 10), minn);
        maxn = max(int(temp % 10), maxn);
        temp /= 10;
    }
    return x + minn * maxn;
}

int main() {
    // freopen("in.txt", "r", stdin);
    int t;
    scanf("%d", &t);
    while(t--) {
        ll ans, n;
        scanf("%lld %lld", &ans, &n);
        for(ll i = 0; i < n - 1; i++) {
            ll temp = judge(ans);
            if(temp == ans) break;
            ans = temp;
        }
        printf("%lld\n", ans);
    }
    return 0;
}

Young Explorers

思路

应该是一个贪心吧。

题意是对于一个分数为\(e\)的选手,只能加入人数大于等于\(e\)的组里,所以我们取每一组的最大值刚好等于其人数,这样就最大化的利用了所有的人,当然进行这一步之前必须得先排序。

代码

#include <bits/stdc++.h>

using namespace std;

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;

const int N = 2e5 + 10;

int a[N];

int main() {
    // freopen("in.txt", "r", stdin);
    IOS;
    int t;
    cin >> t;
    // scanf("%d", &t);
    while(t--) {
        int n;
        cin >> n;
        for(int i = 0; i < n; i++)
            cin >> a[i];
        int sum = 0, ans = 0;
        sort(a, a + n);
        for(int i = 0; i < n; i++) {
            sum++;
            if(a[i] <= sum) {
                sum = 0;
                ans++;
            }
        }
        cout << ans << "\n";
    }
    return 0;
}

Count Triangles

思路

这题是看了别人的思路才写出来的,我一开始一直在枚举\(z\)边试图去找另外两条边的范围,但是一直wa。

  • 我们考虑枚举\(x + y\)的范围, \(min(c + 1, a + b) <= i <= b + c\)
  • 通过x的最大值我们可以确定y的最小值,同时我们也可以通过x的最小值确定y的最大值。

\(x = a\),最大的\(y_{max} = min(i - a, c)\),当\(y = b\),最大的\(x_{max} = min(i - b, b)\)

通过这个我们可以锁定任意的真正的最小的\(x || y\),我们\(x_{min} = i - y_{max}\)\(y_{min} = i - x_{max}\)

这里我们可以得到任意的一段符合条件的x,y的组合,\(num = (x_{max} - x_{min} + 1) = (y_{max} - y_{min} + 1)\)

然后\(z\)的取值区间长度是\(long = min(d - c + 1, i - c)\)

我们每次枚举的区间答案就是\(ans += num * long\)

代码

#include <bits/stdc++.h>

using namespace std;

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;

int main() {
    // freopen("in.txt", "r", stdin);
    IOS;
	ll a, b, c, d, ans = 0;
	cin >> a >> b >> c >> d;
	for(int i = max(a + b, c + 1); i <= b + c; i++) {
		int x = min(i - b, b), y = min(i - a, c);
		x = i - x;
		ll l = min(i - c, d - c + 1);
		ans += l * (y - x + 1);
	}
	cout << ans << "\n";
    return 0;
}

Game With Array

思路

一道构造题,这题应该是比较好想的,当\(2 * n > s\)的时候,我们至少会出现两个一,然后剩下的全是2,这里我们显然可以得到我们所需要的和为\(s\)的所有二进制数,所以这个是侯一定是不可能有解的。

\(2 * n <= s\)的时候我们如何构造,只需要取\(n - 1\)个一,然后最后一个数是\(s - n + 1\)就行了,最后的\(k\)\(n\)这样就可以保证答案的有解性。

代码

#include <bits/stdc++.h>

using namespace std;

#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
typedef long long ll;

int main() {
    // freopen("in.txt", "r", stdin);
    IOS;
    int n, s;
    cin >> n >> s;
    if(2 * n > s)   cout << "NO\n";
    else {
        cout << "YES\n";
        for(int i = 0; i < n - 1; i++)
            cout << "1 ";
        cout << s - (n - 1) << "\n";
        cout << n << "\n";
    }
    // int t;
    // cin >> t;
    // // scanf("%d", &t);
    // while(t--) {

    // }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lifehappy/p/12905630.html