Codeforces Round #599 Div2解题报告A-D

Posted zxytxdy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #599 Div2解题报告A-D相关的知识,希望对你有一定的参考价值。

Codeforces Round #599 Div2解题报告A-D

A. Maximum Square

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
int T, n, a[maxn];
bool cmp(int a, int b){
    return a > b;
}
int main()
{
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        sort(a+1, a+1+n, cmp);
        int ans = 0;
        for(int i = 1; i <= n; i++)
            if(a[i] > ans) ans++;
            else break;
        cout << ans << endl;
    }
    return 0;
}

B1. Character Swap (Easy Version)

  • Easy Version由于只能操作一次,所以只有两个位置不同的时候才能换,然后判断一下两个不同的位置是不是相同的。
#include<bits/stdc++.h>
using namespace std;

void solve()
{
    int n; scanf("%d", &n);
    string s, t, a1="", a2=""; cin >> s >> t;
    int diff = 0;
    for(int i = 0; i < n; i++)
    {
        if(s[i] != t[i])
        {
            diff += 1;
            a1 += s[i];
            a2 += t[i];
        }
    }
    if(diff != 2) {
        puts("No");
        return;
    }
    if(a1[0] == a1[1] && a2[0] == a2[1]) puts("Yes");
    else puts("No");
}

int main()
{
    int T; scanf("%d", &T);
    while(T--) solve();
    return 0;
}

B2. Character Swap (Hard Version)

  • hard version在于可以移动多次。

  • 首先判定能不能得到YES。

  • 分析容易发现只有在每个字符在两个字符串中出现的次数为偶数的时候才可以输出YES。

  • 其实对于输出操作步骤就相当于是构造题。

  • 可以发现,字符串是不长的,只有50。

  • 所以暴力扫描一遍,遇到可以让当前字符满足条件的操作就做下来。

  • 也算是一种贪心吧...

  • #include<bits/stdc++.h>
    #define PII pair<int, int>
    using namespace std;
    int T, n;
    void solve()
    {
        scanf("%d", &n);
        string s, t; cin >> s >> t;
        vector<PII> op;
        for(int i = 0; i < n; i++)
        {
            if(s[i] != t[i])
            {
                for(int j = i+1; j < n; j++)
                {
                    if(s[i] == s[j])
                    {
                        swap(s[j], t[i]);
                        op.push_back({j, i});
                        break;
                    }
                    if(s[i] == t[j])
                    {
                        swap(s[j], t[j]);
                        swap(t[i], s[j]);
                        op.push_back({j, j});
                        op.push_back({j, i});
                        break;
                    }
                }
            }
        }
        if(s != t) {
            puts("NO");
            return;
        }
        puts("YES");
        cout << op.size() << endl;
        for(auto x : op)
            printf("%d %d
    ", x.first+1, x.second+1);
    }
    
    int main()
    {
        scanf("%d", &T);
        while(T--) solve();
        return 0;
    }

C. Tile Painting

  • 题意是有n个瓷砖编号从1到n,有个人想要给瓷砖染色。两块瓷砖的编号分别为(i,j),((i,j)不相邻,也就是(|i-j|>1))。
  • 如果(|i-j|)是一个(n)的因子。那么他们需要染成一个颜色。
  • 问这个人最多用多少种颜色给瓷砖染色。
  • 思维题。
  • 如果(n)是素数,那么他不会有除了(1)和自身的因子,那么就可以输出(n)
  • 如果(n)不是素数,考虑(n=p_i^{c_i})的形式。
  • 如果只有一个质因子,那么输出这个(p)
  • 如果有多个,输出1。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    ll n; cin>>n;
    ll st = 0; ll i;
    for(i = 2; i <= n / i; i++)
    {
        if(n % i == 0) st++;
        while(n % i == 0) n /= i;
    }
    if(st == 0) cout << n << endl; // 如果是素数
    else if(st == 1 && n == 1) cout << i-1 << endl;
    else cout << 1 << endl;
    return 0;
}

D. 0-1 MST

题意描述

  • 给定一张完全图(所有点都有边相连),其中有些边长度为0,有些长度为1,问最小生成树权值大小。

思路

  • 最小生成树有两种算法:(prim)(kruskal),但稍微算一下就知道这是不行的。
  • 输入给出了边权为1的点,我们求出他的补图,假设补图有k个连通块,那么只需要将这k个连通块连接起来就行,那么答案就是(ans=k-1)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int n, m, vis[maxn], ans;
set<int> s, g[maxn];
queue<int> q;

void bfs(int x)
{
    q.push(x);
    vis[x] = 1; s.erase(x);
    while(q.size())
    {
        int t = q.front(); q.pop();
        for(set<int>::iterator it = s.begin(); it != s.end();)
        {
            int tmp = *it++;
            //没有边权为1的边相连
            //说明是一个权为0的连通块
            if(g[tmp].count(t) == 0) 
            {
                s.erase(tmp);
                q.push(tmp);
                vis[tmp] = 1;
            }
        }
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) s.insert(i);
    for(int i = 1, x, y; i <= m; i++)
    {
        scanf("%d%d", &x, &y);
        g[x].insert(y);
        g[y].insert(x);
    }
    for(int i = 1; i <= n; i++)
        if(!vis[i]) bfs(i), ans++;
    cout << ans-1 << endl;
    return 0;
}

以上是关于Codeforces Round #599 Div2解题报告A-D的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #599 (Div. 2)

Codeforces Round #599 (Div. 2) C. Tile Painting

Codeforces Round #599 Div2解题报告A-D

Codeforces Round #599 (Div. 2) A. Maximum Square

Codeforces Round #599 (Div. 2)

Codeforces Round #599 (Div. 2) B1. Character Swap (Easy Version)