ABC 256 C-D
我又双叒叕回来啦!
本场RP = INT_MAX。
C
看上去也没什么巧妙解法,于是决定直接暴力。
然后算了下时间复杂度,$ O(n^9) $的复杂度撑不住呀!
然后……
想了下,发现其实枚举左上4个格子就够了,时间复杂度 $ O(n^4) $,其中 $ n = max(h_1, h_2, h_3, w_1, w_2, w_3) $,可以通过。
暴力万岁
#include <iostream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <vector>
#include <bitset>
#include <stack>
#include <sstream>
#include <algorithm>
using namespace std;
int main() {
int h1, h2, h3, w1, w2, w3;
scanf("%d %d %d %d %d %d", &h1, &h2, &h3, &w1, &w2, &w3);
int a11, a12, a13, a21, a22, a23, a31, a32, a33;
int ans = 0;
for (a11 = 1; a11 < h1 - 1 && a11 < w1 - 1; a11++) {
for (a12 = 1; a11 + a12 < h1; a12++) {
for (a21 = 1; a11 + a21 < w1; a21++) {
for (a22 = 1; a21 + a22 < h2 && a12 + a22 < w2; a22++) {
a13 = h1 - a11 - a12;
a23 = h2 - a21 - a22;
a31 = w1 - a11 - a21;
a32 = w2 - a12 - a22;
if (h3 - a31 - a32 == w3 - a13 - a23 && h3 - a31 - a32 > 0) {
ans++;
}
}
}
}
}
printf("%d", ans);
return 0;
}
D
解法一:前缀和
我们把这些区间内的元素看做1,其余的看做0,那么本题就成了找连续的1。
但是有个问题:直接赋值会超时。
我们用前缀和来优化:左边+1,右边-1。
这样中间的就都为1了。
前缀和有个特点,就是他会累加前面的。
所以,1 0 0 0 0 0 -1 0 0 会变成 1 1 1 1 1 1 0 0 0。
然后多个1 0跑一边就能全部带走,所以就不会超时了。
时间复杂度: $ O(n) $
#include <iostream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <utility>
#include <queue>
#include <vector>
#include <bitset>
#include <stack>
#include <sstream>
#include <algorithm>
using namespace std;
#define maxn 200005
int prefix[maxn];
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
int l, r;
scanf("%d %d", &l, &r);
prefix[l]++;
prefix[r]--;
}
for (int i = 1; i < maxn; i++) {
prefix[i] += prefix[i - 1];
}
int ansl, ansr;
bool flag = false;
for (int i = 0; i < maxn; i++) {
if (prefix[i] && !flag) {
flag = true;
ansl = i;
}
if (!prefix[i] && flag) {
flag = false;
ansr = i;
printf("%d %d\n", ansl, ansr);
}
}
return 0;
}
解法二:直接模拟
先把区间存到pair里,然后排一下序。
遍历的时候,如果这个区间和上一个合并过的区间有交点的话,那就更新一下右端点。
如:[10, 13) 和 [12, 48)有交点(12),但[8, 67)和[122, 514)没有交点。
由于博主懒,这里就先不贴代码了。