Codeforces Round #655 (Div. 2) A-D --白话题解

//头
#include <iostream>
#include <stdio.h>
#include<cstring>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<unordered_map>
#include<time.h>
#define F(i,a,b) for(int i=a;i<=b;i++)
#define FD(i,b,a) for (int i=b;i>=a;i--)
#define ll long long
#define db double
using namespace std;
const ll pm = 1e9 + 7;
const ll inf = 2147482647;

A.终极无敌宇宙第二之除了A+Bproblem没有别的问题更简单之46亿年难遇大水题
输出n个1就行

int main()
{
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        F(i, 1, n) {
            printf("1 ");
        }printf("\n");
    }
    return 0;
}

B. 开题的思路在于 如果是偶数的话 那么显然两个a = n/2 ,b = n/2 就是答案
而想让LCM最小,那么正好是两个数中更大的那一个数才是最小 也就是a整除b(假设b更大)

基于这两点,我们尝试把n分成最少的i等分
如果能刚好分出i等分 那么其中一份是a 另一份是b (保证了a总能整除b 整除倍数为i-1)
如果n为质数 当然一份是1 另一份n-1了!

int main()
{
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        int f = 0;
        F(i, 2, sqrt(n)) {
            if (f) break;
            if (n % i == 0) {
                int a = n / i;
                int b = n - a;
                cout << a << ' ' << b << endl;
                f = 1;
            }
        }
        if (!f) {
            cout << 1 << ' ' << n - 1 << endl;
        }
    }


    return 0;
}

C. 对于一个未知顺序的序列,如果本身就是与1234…n全错位的,当然只要一次就能完成排序
如果有若干个不是错位的 比如3214…n中有2和4是不错位的,那么需要2步才能完成排序:
第一次变成全错位,第二次变成顺序排列。
所以答案为0、1、2三种

int main()
{
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        F(i, 1, n) {
            cin >> a[i];
        }
        int L = 0, R = n+1;
        F(i, 1, n) {
            if (a[i] != i)break; else L = i;
        }
        FD(i, n, 1) {
            if (a[i] != i) break; else R = i;
        }
        int ans = 0;
        if (L + 1 < R + 1)ans = 1;
        F(i, L+1, R-1) {
            if (a[i] == i)ans = 2;
        }
        cout << ans << endl;

    }


    return 0;
}

D . 被卡住了,还好没参加rated(划掉),
一开始想的是每次操作都选择去掉最小的,然而是错误的贪心,比如1 10 10 100 100就不适合这个策略 (贪心200 正解应该是 210)
出现以上问题的原因就是贪心让10+10的一个组合被去掉了,最后答案变成了100+100
而正解应该是尽量避免出现使得某个ai+ai+2的组合数被去掉
所以应该是一个隔着一个去当被去掉的那(n-1)/2数,
那么答案就是剩下的一个隔着一个的(n+1)/2个数的总和。
这样的总和中取最大的那一个(因为n为基数 所以说一个隔着一个而且是环状的话情况是(n-1)/2种 而n为偶数只有2种情况)
但是为什么一定是这样的呢 不会因为为了凑满(n+1)/2的数而放弃一些很大的数么 看了CF的评论区也没找到有价值的证明 欢迎头脑风暴!

int a[200020] = {};
int b[400020] = {};
queue<int> q;
int main()
{
    int n;
    cin >> n;
    F(i, 1, n) {
        cin >> a[i];
    }
    int pos = 0;
    int mid = (n+1)/ 2;
    F(i, 1, n) {
        if (i % 2 == 1) {
            pos++;
            b[pos] = a[i];
        }
        else {
            b[mid + pos] = a[i];
        }
    }
    F(i, 1, n) {
        b[n + i] = b[i];
    }
    ll ans = 0;
    ll max = 0;
    F(i, 1, 2 * n) {
        q.push(b[i]);
        ans += b[i];
        if (q.size() > (n + 1) / 2) {
            ans -= q.front();
            q.pop();
        }
        if (ans > max)max = ans;
        cout << ans << endl;
    }
    cout << max << endl;


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值