Codeforces Round #599 (Div. 2)

A - Maximum Square

题意:给 \(n\) 块宽度为 \(1\) 长度为 \(a_i\) 的木板,把这些木板拼在一起,求最大形成的正方形的边长。

题解:贪心,从大到小排序,然后找第一个满足 \(a_i<i\) 的位置break掉。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int n, a[1005];

int main() {
#ifdef KisekiPurin
    freopen("KisekiPurin.in", "r", stdin);
#endif // KisekiPurin
    int t;
    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, greater<int>());
        int ans = 0;
        for(int i = 1; i <= n; ++i) {
            if(a[i] >= i)
                ans = i;
            else
                break;
        }
        printf("%d\n", ans);
    }
}

B1 - Character Swap (Easy Version)

题意:给两个互异的字符串 \(s\)\(t\) ,必须选择某个 \(s[i]\)\(t[j]\) 交换恰好1次,问能否使得两个字符串相等。

题解:交换恰好1次应该是最多减少两个不等的位置,找出不等的位置之后判断是不是恰好只有两个,若是,则直接交换然后判断相等,否则直接No。

注:由于是互异的所有不用特判0,否则0是一定合法的(交换(1,1))。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

int n;
char s[10005], t[10005];

int main() {
#ifdef KisekiPurin
    freopen("KisekiPurin.in", "r", stdin);
#endif // KisekiPurin
    int k;
    scanf("%d", &k);
    while(k--) {
        scanf("%d%s%s", &n, s + 1, t + 1);
        vector<int> dif;
        for(int i = 1; i <= n; ++i) {
            if(s[i] != t[i])
                dif.push_back(i);
        }
        if(dif.size() != 2) {
            puts("No");
        } else {
            swap(s[dif[0]], t[dif[1]]);
            if(strcmp(s + 1, t + 1) == 0)
                puts("Yes");
            else
                puts("No");
        }
    }
}

B2 - Character Swap (Hard Version)

题意:给两个互异的字符串 \(s\)\(t\) ,选择某个 \(s[i]\)\(t[j]\) 交换不超过 \(2n\) 次,问能否使得两个字符串相等。

题解:很显然有解的必要条件就是所有的字母出现都是偶数次,先判断这个。其次满足上面的必要条件之后必定有解,因为使用最多2次交换就可以消除至少1个位置上的不同。具体的做法是:固定已经相等的前半部分,然后假如 \(s[i] \neq t[i]\),如果有某个后面的 \(s[id]=s[i]\) ,那么就把 \(s[id]\)\(t[i]\) 交换。否则,必定存在某个后面的 \(t[id]=s[i]\) ,但是 \(t[id]\) 不能直接与 \(t[i]\) 交换,所以让它与 \(s[n]\) 交换(这样比较好写),然后把 \(s[n]\)\(t[i]\) 交换。

注:输出要先输出 \(i\) 再输出 \(j\) ,这个WA不值得。

C - Tile Painting

题意:给排成一行的 \(n\) 个格子,要求所有的 \(i,j\) 满足 \(|i-j|\)\(n\) 的因子的,都要同色,求最大的涂色数。

题解:非常显然就是所有质因子的gcd,当然因为都是质因子所有直接判断有没有多种然后输出 \(1\) 就可以,为什么要放在C题坑人,放在B题不好吗。

D - 0-1 MST

题意:给一个 \(n\) 个节点的完全图,有 \(m\) 条权为1的边,其他的边权为0,求最小生成树的权值和。

题解:改写Prim算法,放三个容器,一个权为无穷(未知),一个权为0,一个权为1,每次优先取出0容器里面的扩展,不消耗任何东西,否则取出1容器的扩展,cost++。扩展的时候1容器可以从无穷容器夺取节点,0容器可以从1容器夺取节点,所以1容器和无穷容器应该是set。复杂度想不明白。

注:换了好几次做法,最后应该是时间不够,浪费太多在前面换来换去了,应该是类似0-1BFS的思路,改写Prim算法。???这样魔改之后不就是0-1BFS了吗?就直接用0-1BFS就可以了。

猜你喜欢

转载自www.cnblogs.com/KisekiPurin2019/p/11809724.html