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就可以了。