原题链接
题意:现有随机的01串 ,请从中选取两个子串进行或运算,使得最终答案最大。
容易想到主串本身一定被选中,不妨设其为s1.
若s2右端点确定,则l = 1时一定最优,
若s2长度为len, 则答案前n - len位不受影响,而答案最好要让第一个0变成1.
随机数据下枚举r = n, r递减,枚举50次.
当主串前50位有0时答案一定正确,该条件不成立的概率只有1/2^50, 随机数据下表现优秀。
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
char s[N];
bitset<N> a, ans;
int n;
bitset<N> Max(bitset<N> a, bitset<N> b) {
for (int j = n - 1; j >= 0; --j) {
if (a[j] > b[j]) return a;
if (a[j] < b[j]) return b;
}
return a;
}
int main() {
scanf("%d", &n);
scanf("%s", s);
for (int i = 0; i < n; ++i) {
a[i] = s[n - i - 1] - '0';
}
for (int j = 0; j < 50; ++j) {
ans = Max(ans, a | (a >> j));
}
int flag = 0;
for (int i = n - 1; i >= 0; --i) {
if (ans[i] == 0) { if (flag) putchar('0'); }
else putchar('1'), flag = 1;
}
if (!flag) putchar('0');
return 0;
}
注意:
1.抓住随机数据的性质,正解正确性不完全保证。
2.oi赛制下贪心骗分。