首页 > 其他分享 >2023.1.6 (Codeforces Round #842 (Div. 2))

2023.1.6 (Codeforces Round #842 (Div. 2))

时间:2023-01-07 01:22:06浏览次数:67  
标签:842 int flag cin fa 2023.1 https Div com

A.Greatest Convex

https://codeforces.com/contest/1768/problem/A

Description

求出最大的 \(x (1 \leq x < k)\),使得 \(x! + (x - 1)!\) 是 \(k\) 的倍数。

Solution

\[x! + (x - 1)! = (x + 1) \cdot (x - 1)! \]

当 \(x = k - 1\)时,\((x + 1) \cdot (x - 1)! = k \cdot (k - 2)!\),该值始终为 \(k\) 的倍数。故输出 \(k - 1\)即可。

Code

https://codeforces.com/contest/1768/submission/188069238

B.Quick Sort

https://codeforces.com/contest/1768/problem/B

Description

定义一种操作:对一个长度为 \(n\) 的排列,每次可以从排列中任意选出 \(m\) 个数(将这些数从原排列中删除),将他们按升序排列后加到原排列末尾。最小化使得这个长度为 \(n\) 的排列整体升序的操作次数。

Solution

需要发现,以 \(1\) 为开头的、连续的上升序列,这些数字是不用选中的,其余的都需要选。直接计算 \(\lceil \frac {n - length} {m} \rceil\) 即可。

Code

/********************************************************
> File Name: b.cpp
> Author: zylll
> Blog: https://www.cnblogs.com/BeyondLimits/ 
> Created Time: 四  1/ 5 22:48:52 2023
 *******************************************************/
#include <bits/stdc++.h>
const int N = 2e5 + 5;
using namespace std;
int T, n, m, a[N];
int main() {
    ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	freopen("in","r", stdin);
    cin >> T;
    while (T--) {
        int cnt = 0;
        cin >> n >> m;
        for (int i = 1; i <= n; i++) cin >> a[i];
        int now = 1;
        for (int i = 1; i <= n; i++) {
            if (a[i] == now) now++;
        }
        cout << (n - now + 1 + m - 1) / m << endl;
    }
	return 0;
}

C. Elemental Decompress

https://codeforces.com/contest/1768/problem/C

Description

给定一个序列 \(a_n\),询问是否存在两个长度为 \(n\) 的排列 \(p_n,q_n\),使得 \(a_i = max(p_i, q_i), 1 \leq i \leq n\)。若存在,需输出方案。

Solution

出现以下任意一种情况都是无解的:\(a_n\)中未出现过\(n\)、\(a_n\)中\(1\)的出现次数大于\(1\)、\(a_n\)中任意一个数字的出现次数大于\(2\)。

确定有解后,先把那些一定要填的数字填好,剩余数字结合贪心思路,每次能往大里填(结合\(lower\)_\(bound\)即可)。

Code

/********************************************************
> File Name: c.cpp
> Author: zylll
> Blog: https://www.cnblogs.com/BeyondLimits/ 
> Created Time: 四  1/ 5 23:00:22 2023
 *******************************************************/
#include <bits/stdc++.h>
const int N = 2e5 + 5;
using namespace std;

int T, n, cnt[N], a[N], ans1[N], ans2[N];
bool vis1[N], vis2[N];
vector<int> fi, se;

int main() {
    ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
    freopen("in","r", stdin);
    cin >> T;
    while (T--) {
        bool flag = false;
        cin >> n;
        for (int i = 1; i <= n; i++) cnt[i] = 0;
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            cnt[a[i]]++;
            if (cnt[a[i]] > 2) flag = true;
        }
        flag |= (cnt[1] == 2);
        flag |= (!cnt[n]);
        if (flag) cout << "NO" << endl;
        else {
            fi.clear();
            se.clear();
            for (int i = 1; i <= n; i++) {
                vis1[i] = vis2[i] = false;
                ans1[i] = ans2[i] = 0;
            }
            for (int i = 1; i <= n; i++) {
                if (!vis1[a[i]]) {
                    vis1[a[i]] = true;
                    ans1[i] = a[i];
                }
                else {
                    ans2[i] = a[i];
                    vis2[a[i]] = true;
                }
                if (a[i] == 1) {
                    vis1[1] = vis2[1] = true;
                    ans1[i] = ans2[i] = 1;
                }
            }
            for (int i = n; i >= 1; i--) {
                if (!vis1[i]) se.push_back(i);
                if (!vis2[i]) fi.push_back(i);
            }
            for (int i = 1; i <= n; i++) {
                if (!ans1[i]) {
                    auto it = lower_bound(se.begin(), se.end(), ans2[i], greater<int>());
                    if (it == se.end()) {
                        flag = true;
                        break;
                    }
                    ans1[i] = se[it - se.begin()];
                    se.erase(it);
                }
            }
            for (int i = 1; i <= n; i++) {
                if (!ans2[i]) {
                    auto it = lower_bound(fi.begin(), fi.end(), ans1[i], greater<int>());
                    if (it == fi.end()) {
                        flag = true;
                        break;
                    }
                    ans2[i] = fi[it - fi.begin()];
                    fi.erase(it);
                }
            }
            if (flag) cout << "NO" << endl;
            else {
                cout << "YES" << endl;
                for (int i = 1; i <= n; i++) {
                    cout << ans1[i];
                    i == n ? cout << endl : cout << " ";
                }
                for (int i = 1; i <= n; i++) {
                    cout << ans2[i];
                    i == n ? cout << endl : cout << " ";
                }
            }
        }
    }
	return 0;
}

D.Lucky Permutation

https://codeforces.com/contest/1768/problem/D

Description

定义一种操作:对一个长度为 \(n\) 的排列 \(a_n\),每次可以从排列中选出 \(i\) 和 \(j\) ,交换 \(a_i\) 与 \(a_j\)。最小化使得最终的 \(a_n\) 有且仅有一个逆序对的操作次数。

Solution

对于每个 \(i\),若考虑从 \(a_i\) 到 \(i\) 连一条有向边,根据排列的性质(每个点的入度和出度都为 \(1\)),则会生成 \(x\) 个环 \((1 \leq x \leq n)\)。

不难发现,最终状态一定是「一个升序排列,且选择一对相邻的数交换后」的形式。若按之前的图的形式表示,则可以表示为 \(n - 1\) 个自环 + \(1\) 个长度为 \(2\) 的环(且这个长度为 \(2\) 的环,是由两个相邻的数字构成的)。

对于原排列表示出的 \(x\) 个环,自环可以不管,大环则需要被拆解成小环和自环。当交换两个数有效时,可以等效为「大环变小,且新增自环」。若存在一个大环其中包含两个相邻的数,那么意味着在拆解的过程中,可以把他们俩留下,其他变为自环。否则在所有大环拆成自环后,还需要选择两个相邻的自环,将他们变成长度为 \(2\) 的环。

利用并查集可以找出环的个数后,再在每个环中判断,是否存在相邻元素。若存在则答案 \(-1\),不存在则答案 \(+1\)。

Code

/********************************************************
> File Name: d.cpp
> Author: zylll
> Blog: https://www.cnblogs.com/BeyondLimits/ 
> Created Time: 五  1/ 6 23:17:07 2023
 *******************************************************/
#include <bits/stdc++.h>
const int N = 2e5 + 5;
using namespace std;

int T, n, x, fa[N];
set<int> s, son[N];

int get_fa(int x) { return x == fa[x] ? x : fa[x] = get_fa(fa[x]); }

int main() {
    ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	freopen("in","r", stdin);
    cin >> T;
    while (T--) {
        bool flag = false;
        cin >> n;
        for (int i = 1; i <= n; i++) fa[i] = i;
        for (int i = 1; i <= n; i++) {
            cin >> x; 
            int fx = get_fa(i), fy = get_fa(x);
            fa[fy] = fx;
        }
        for (int i = 1; i <= n; i++) {
            int x = fa[i];
            while (x != fa[x]) x = fa[x];
            s.insert(x);
            son[x].insert(i);
        }
        for (int i = 1; i <= n; i++) {
            int last = -1;
            for (auto x : son[i]) {
                if (last != -1 && x - last == 1) {
                    flag = true;
                    break;
                }
                last = x;
            }
            if (flag) break;
        }
        cout << n - (int)s.size() + (!flag ? 1 : -1) << endl;
        s.clear();
        for (int i = 1; i <= n; i++) son[i].clear();
    }
	return 0;
}

标签:842,int,flag,cin,fa,2023.1,https,Div,com
From: https://www.cnblogs.com/BeyondLimits/p/17032035.html

相关文章

  • 2023.1.6
    搜索了某些学校的心理学培养方案,并没有找到相应的课本和参考教材。有几个可以参考下:【资料整理】如何看到国内外各大学的课表、课程大纲,https://zhuanlan.zhihu.com/p/4......
  • Codeforces Round #842 (Div. 2)
    CodeforcesRound#842(Div.2)https://codeforces.com/contest/1768好困,放完代码就跑路。A.GreatestConvex#include<bits/stdc++.h>usingnamespacestd;void......
  • Codeforces Round #842 (Div. 2)
    Preface唉现在这是是做稍微难点的SB题(指Div2正常场的CD难度)总是要犯病因此Rating上不去不说,比赛的时候连EF题面都没机会看一眼这场先是C交上去忘记本机调试的时候把数组......
  • Codeforces Round 842
    目录写在前面ABCDE写在最后写在前面仁王真好玩大太刀真好玩下辈子我还要玩大太刀[](https://pic.imgdb.cn/item/63b7fdb4be43e0d30ec2dccd.jpg)顺带吐槽一下,这什么排......
  • 《Quantifying the effects of environment and population diversity in multi-agent
    量化多智能体强化学习中环境和种群多样性的影响总结:在多种实验环境下评估多智能体强化学习受到环境多样性以及智能体多样性的影响,主要是泛化能力实验过程主要是通过改......
  • Codeforces Round #842 (Div. 2)
    题目链接A核心思路:样例模拟出答案。#define_CRT_SECURE_NO_WARNINGS#include<iostream>#include<cstring>#include<algorithm>#include<vector>#include<bits/std......
  • Codeforces Round #842 (Div. 2) A-D
    比赛链接A题意给一个数\(k\)找到最大的\(x\),满足\(1\leqx<k\)且\(x!+(x-1)!\)是\(k\)的倍数。题解知识点:数学。猜测\(x=k-1\),证明\((k-1)!+(k-......
  • 关系运算符、逻辑运算符——the thirteenth——2023.1.5
    关系运算符  在C语言中=是赋值的意思,而==才是等于的意思  逻辑运算符一共有三种:&&(并且)、||(或者)、!(非)年龄:取值16-50岁。身高:取值150cm-190cm。身材:1-火辣;2-......
  • 1.6 vp Polynomial Round 2022 (Div. 1 + Div. 2, Rated, Prizes!)
    A-AddPlusMinusSign题意:给出01字符串,可以在每两个字符中间任意添加‘+’,‘-’。最后要使表达式的绝对值最小思路:设表达式的值为\(cnt\),若当前\(cnt\)大于\(0\),不管......
  • 2023.1.6 DP 学习日志
    今天还是学DP,干了两道题1.最长上升子序列II(AcWing.896)数据加强版的最长上升子序列不能直接DP,还得二分(其实有点像贪心)比较简单思路就不写了。其实我WA了五次code:#inc......