Codeforces Round #655 (Div. 2)解题报告

4 篇文章 0 订阅
3 篇文章 0 订阅

Codeforces Round #655 (Div. 2)解题报告

A - Omkar and Completion

思路

一开始还在思考怎么构造,然后通篇没看见说构造的元素不能重复,那就全1好了……

代码

//
// Created by Visors on 2020/7/11.
//

#include <iostream>

using namespace std;

int main() {
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        for (int i = 1; i < n; i++) cout << 1 << ' ';
        cout << 1 << endl;
    }
    return 0;
}

B - Omkar and Last Class of Math

思路

求的是LCM,那么会有如下分析:

b = n − a b=n-a b=na
L C M ( a , b ) = L C M ( a , n − a ) LCM(a,b)=LCM(a,n-a) LCM(a,b)=LCM(a,na)

假设 a ≤ n − a < n a\leq n-a<n ana<n,那么有 a ≤ n 2 a\leq \frac{n}{2} a2n,且

  1. a ∣ ( n − a ) a\mid (n-a) a(na),那么 L C M ( a , n − a ) = n − a < n LCM(a,n-a)=n-a<n LCM(a,na)=na<n
  2. a ∤ ( n − a ) a\nmid (n-a) a(na),那么 L C M ( a , n − a ) = k ∗ ( n − a ) LCM(a,n-a)=k*(n-a) LCM(a,na)=k(na),其中 k > 1 k>1 k>1且为整数,那么显然 L C M ( a , n − a ) ≥ 2 ∗ ( n − a ) ≥ n > n − a LCM(a,n-a)\geq 2*(n-a)\geq n > n-a LCM(a,na)2(na)n>na

由上推论,易知若有 1 1 1,则取 1 1 1情况可以得到比其他 2 2 2情况更好的结果。因为有 a ∣ ( n − a ) a\mid (n-a) a(na),所以有 n − a = k ∗ a n-a=k*a na=ka n = ( k + 1 ) ∗ a n=(k+1)*a n=(k+1)a,由是我们可以令 a n s = n ans=n ans=n,从小到大枚举 k k k,因为 n n n为定值不变,所以 k k k越小, a a a越大,从而 n − a n-a na越小,即 L C M ( n , n − a ) LCM(n,n-a) LCM(n,na)越小。按此推论写出代码即可。

代码

//
// Created by Visors on 2020/7/11.
//

#include <iostream>
#include <cmath>

using namespace std;

int main() {
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        int ans = n;
        int len = sqrt(n);
        for (int i = 2; i <= len; i++)
            if (n % i == 0) {
                ans = i;
                break;
            }
        cout << n / ans << ' ' << n - n / ans << endl;
    }
    return 0;
}

C - Omkar and Baseball

思路

首先认识一点,由于数字是 1 ∼ n 1\sim n 1n,所以对于从小到大的有序数列有 a i = i a_i=i ai=i,我们暂且称满足该式的 a i a_i ai称为在原位,不满足该式的称为错位。

题目看上去有点难,仔细分析,其实任意数列需要的最小操作次数都不会超过 2 2 2

  1. 不用操作:如果数列本就有序,当然不用操作。
  2. 操作一次:显然,如果给定的序列中有且仅有一串连续的错位数字(也可能是一个数字),则一次操作对这串(这个)数字进行特殊交换,即可得到各个数字都在原位的序列。
  3. 操作两次:如果给定的序列有多串(不同串间被在原位的数字隔开)连续的错位数字(同样也可能是一个数字),思考我们可以找到第一个错位的数字和最后一个错位的数字,然后对这个区间内的数字进行特殊交换。怎么做这次交换呢?一次交换就想把这串数字归位显然是不行的,我们可以先将这串数字打乱,使得他们全部错位,然后再特殊交换一次,使他们全部归位。

代码

//
// Created by Visors on 2020/7/11.
//

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        vector<int> v(n);
        for (auto &it:v) {
            cin >> it;
            it--;
        }
        bool flag = true;
        for (int i = 1; i < v.size(); i++)
            if (v[i - 1] > v[i]) {
                flag = false;
                break;
            }
        if (flag) {
            cout << 0 << endl;
            continue;
        }
        int status = 0, ans = 1; // status: 0-都是原位 1-有连续错位 2-错位后又有原位
        for (int i = 0; i < v.size(); i++) {
            if (v[i] == i) {
                if (status == 1) status = 2;
            } else {
                if (status == 0) status = 1;
                else if (status == 2) {
                    ans = 2;
                    break;
                }
            }
        }
        cout << ans << endl;
    }
}

D - Omkar and Circle

过些时日再整理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值