Codeforces Round #818 (Div. 2) A - D题解

Codeforces Round #818 (Div. 2) A - D题解

A

题意

找出共有多少对数(a, b), 满足 l c m ( a , b ) g c d ( a , b ) ≤ 3 \frac{lcm(a, b)}{gcd(a, b)}\leq 3 gcd(a,b)lcm(a,b)3 ,其中 1 ≤ a , b ≤ 3 1 \leq a , b \leq3 1a,b3

思路

显然 lcm(a, b) = x * gcd(a, b) <= 3 * gcd(a, b),显然假如a >= b,当a为b的1、2、3倍时满足条件

代码

void solve()
{
    int n;
    cin >> n;
    cout << n + n / 2 * 2 + n / 3 * 2 << '\n';
}

B

题意

在nn的方格中要求任意1k或k*1的格子中存在至少一个’X’,和给出的第r行c列必须为’X’,题目保证给出的n是k的倍数。

思路

对于每行来说保证两个’X’之间最多间隔k - 1个格子,由于n是k的倍数,可以发现当‘X’上下交错安放时满足条件

代码

const int N = 505;
char a[N][N];
int n, k, r, c;
 
void solve()
{
    memset(a, '.', sizeof(a));
    cin >> n >> k >> r >> c;
    int d = n / k;
    --r, --c;
 
    for (int i = 0, p = r; i < n; ++i, c = (c + 1) % n, p = (p + 1) % n)
    {
        for (int j = 0, q = c; j < d; ++j, q = (q + k) % n)
            a[p][q] = 'X';        
    }
 
 
    for (int i = 0; i < n; ++i) a[i][n] = 0;
    for (int i = 0; i < n; ++i) cout << a[i]<< '\n';
}

C

题意

给出数组a和b,在一个操作中如果 a i ≤ a ( i + 1 ) % n a_{i} \leq a_{(i + 1) \% n} aia(i+1)%n,则 a i = a i + 1 a_{i} = a_{i} + 1 ai=ai+1判断是否能进行操作使得数组a等于b。

思路

首先a不能减小,因此需满足 a i ≤ b i a_{i} \leq b_{i} aibi,其次当 a i ! = b i a_{i} != b_{i} ai!=bi时需要 b i ≤ b ( i + 1 ) % n + 1 b_{i} \leq b_{(i + 1) \% n } + 1 bib(i+1)%n+1才能构造。接下来证明只需要满足这些条件即可构造出来:
在进行操作时假如说 a i > a i + 1 a_{i} > a_{i + 1} ai>ai+1我们可以想象出一条边从 a i + 1 a_{i + 1} ai+1指向 a i a_{i } ai,显然图中没有环,就可以按照拓扑序列进行相加,使得序列满足要求。

代码

const int N = 2e5 + 10;
int a[N], b[N], n;
 
void solve()
{
    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i];
    for (int i = 0; i < n; i++) cin >> b[i];
    for (int i = 0; i < n; i++) 
    {
        int j = (i + 1) % n;
        if (a[i] > b[i] || (a[i] != b[i] && b[i] > b[j] + 1)) return cout << "NO\n", void(0); 
    }
    cout << "YES\n";
}

D

题意

共有 2 n 2^{n} 2n个人进行比赛,按顺序两两pk胜者进入下一轮。Madoka可以任意安排开始时人员顺序,以及每轮中时是左边获胜还是右边获胜,而最终获胜的人序号越靠前,他赢得越多。而比赛方可以选择交换最多k对人,使得Madoka赢得少一些,问Madoka能保证自己安排到的最小编号是几。请添加图片描述

思路

因为一个点的左右子树交换不影响结果,为了方便观察,将所有选择转到左子树,从根结点沿着选择的边所到达的叶子结点即为获胜者,每次选择则是将路径转向右子树,因此在k次选择中 ∑ i = 0 k C n i \sum_{i = 0}^{k} \textrm{C}_{n}^{i} i=0kCni即为能选择到的点,因此Madoka将这些点的值设为较小值,即为答案

代码

const ll mod = 1e9 + 7;
const int N = 1e5 + 10;
ll ji[N];
 
ll C(const int& a, const int& b)
{
    return ji[a] * inv(ji[b], mod) % mod * inv(ji[a - b], mod) % mod;
}
 
void init()
{
    ji[0] = 1;
    for (ll i = 1; i < N; ++i) ji[i] = ji[i - 1] * i % mod;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绝尘JC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值