码迷,mamicode.com
首页 > 其他好文 > 详细

AtCoder Beginner Contest 178

时间:2020-09-18 01:08:34      阅读:29      评论:0      收藏:0      [点我收藏+]

标签:www   res   合数   转化   using   codeforce   长度   force   tco   

比赛链接:https://atcoder.jp/contests/abc178/tasks

A - not

题意

给出一个整数 $0 \le x \le 1$,如果 $x$ 是 $0$ 就输出 $1$,如果 $x$ 是 $1$ 就输出 $0$ 。

题解

输出 $x \oplus 1$ 或 $!x$ 均可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int x;
    cin >> x;
    cout << (x ^ 1)<< "\n";
    return 0;
}

B - Product Max

题意

给出 $a,b,c,d$,问 $x \times y$ 的最大值。($-10^9 \leq a \leq x \leq b \leq 10^9$,$-10^9 \leq c \leq y \leq d \leq 10^9$)

题解

相似题目:CF1406B,枚举四个端点之积即可。

简单解释一下:

  • 当 $x,y$ 均为正数或正端点之积较大,此时答案为 $b \times d$
  • 当 $x,y$ 均为负数或负端点之积较大,此时答案为 $a \times c$
  • 当 $x,y$ 一方为正数一方为负数,此时答案为 $a \times d$ 或 $b \times c$

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    long long a, b, c, d;
    cin >> a >> b >> c >> d;
    cout << max({a * c, a * d, b * c, b * d}) << "\n";
    return 0;
}

C - Ubiquity

题意

找出满足以下条件的长为 $n$ 的不同序列的个数:

  • $0 \le a_i \le 9$
  • 序列中至少有一个 $a_i = 0$
  • 序列中至少有一个 $a_i = 9$

答案对 $10^9+7$ 取模。

题解

总的序列个数为 $10^n$,

不含 $0$ 的序列个数为 $9^n$,

不含 $9$ 的序列个数为 $9^n$,

不含 $0$ 和 $9$ 的序列个数为 $8^n$,

根据容斥原理,答案即 $10^n - 2 \times 9^n + 8 ^ n$ 。

代码

#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;

int binpow(int a, int b) {
    int res = 1;
    while (b) {
        if (b & 1) res = 1LL * res * a % MOD;
        a = 1LL * a * a % MOD;
        b >>= 1;
    }
    return res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    cout << (0LL + binpow(10, n) - 2 * binpow(9, n) + binpow(8, n) + 2 * MOD) % MOD << "\n";
    return 0;
}

D - Redistribution

题意

给出一个正整数 $s$,问有多少序列满足 $a_i \ge 3$,且序列和为 $s$,答案对 $10^9+7$ 取模。

题解一

设 $dp_i$ 为序列和为 $i$ 的序列个数。

初始时只有序列为空这一种情况,即 $dp_0 = 1$,之后每次向序列中添加大于等于 $3$ 的元素,最终答案即 $dp_s$ 。

代码

#include <bits/stdc++.h>
using namespace std;
constexpr int MOD = 1e9 + 7;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int s;
    cin >> s;
    vector<int> dp(2020);
    dp[0] = 1;
    for (int i = 0; i <= s; i++) {
        for (int j = 3; i + j <= s; j++) {
            (dp[i + j] += dp[i]) %= MOD;
        }
    }
    cout << dp[s] << "\n";
    return 0;
}

题解二

已知序列和为 $s$ ,枚举序列的长度 $i$ 。

因为每个元素都大于等于 $3$,假设每个元素都为 $3$ ,可以将多出来的 $ s-3*i$ 个 $1$,看作 $n$ 个相同的小球放入 $m=i$ 个可为空的相同的盒子中。

此时即转化为组合数学十二路问题中的 $ULA$ 问题,答案即 $\sum_{i = 1}^{\lfloor \frac{s}{3} \rfloor}C_{n+m - 1}^{m - 1}$ 。

代码

#include <bits/stdc++.h>
using namespace std;
constexpr int N = 1e6 + 100;
constexpr int MOD = 1e9 + 7;

int fac[N], inv[N];

int binpow(int a, int b) {
    int res = 1;
    while (b) {
        if (b & 1) res = 1LL * res * a % MOD;
        a = 1LL * a * a % MOD;
        b >>= 1;
    }
    return res;
}

int C(int n, int m){
    if(m < 0 or m > n) return 0;
    return 1LL * fac[n] * inv[m] % MOD * inv[n - m] % MOD;
}

void Init(){
    fac[0] = 1;
    for (int i = 1; i < N; i++) fac[i] = 1LL * fac[i - 1] * i % MOD;
    inv[N - 1] = binpow(fac[N - 1], MOD - 2);
    for (int i = N - 2; i >= 0; i--) inv[i] = 1LL * inv[i + 1] * (i + 1) % MOD;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    Init();
    int s; 
    cin >> s;
    long long ans = 0;
    for (int i = 1; i <= s / 3; i++) {
        (ans += C(s - 3 * i + i - 1, i - 1)) %= MOD;
    }
    cout << ans << "\n";
    return 0;
}

E - Dist Max

题意

在二维平面中给出 $n$ 个点,问两点间的最远曼哈顿距离。

题解

$(x_i,y_i), (x_j, y_j)$ 间的曼哈顿距离为 $|x_i-x_j| + |y_i-y_j|$ 。

假设 $x_i \ge x_j$,那么两点间的距离可能有两种情况:

  • $(x_i-x_j) + (y_i-y_j)$,移项得:$(x_i+y_i) - (x_j+ y_j)$
  • $(x_i-x_j) + (y_j-y_i)$,移项得:$(x_i-y_i) - (x_j- y_j)$

所以对于每个点的坐标 $(x,y)$,分别用两个数组存储 $x+y$ 和 $x-y$,然后取两个数组较大的最值差即可。

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<int> a(n), b(n);
    for (int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        a[i] = x + y;
        b[i] = x - y;
    }
    sort(a.begin(), a.end());
    sort(b.begin(), b.end());
    cout << max(a.back() - a.front(), b.back() - b.front()) << "\n";
    return 0;
}

F - Contrast

题意

给出两个非递减序列 $a$ 和 $b$,问能否重排 $b$ 使得 $a_i \ne b_i $ 。

题解

待填。

 

AtCoder Beginner Contest 178

标签:www   res   合数   转化   using   codeforce   长度   force   tco   

原文地址:https://www.cnblogs.com/Kanoon/p/13666288.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!