voidsolve(){int n;
cin >> n;
string s;
cin >> s;for(int i =0; i < n; i++)cin >> a[i];int sum =0;for(int i =0; i < n; i++){if(s[i]=='0'&& s[i +1]=='1'){int id = i +1, id2 = i;int mi = a[i];while(s[id]=='1'){if(a[id]< mi){
id2 = id;
mi = a[id];}
id++;}if(id2 != i){for(i; i < id2; i++){
sum += a[i];}
s[id2]='0';}}elseif(s[i]=='1')sum += a[i];}
cout << sum << endl;for(int i =0; i <= n; i++)a[i]=0;}
D.Problem with Random Tests
题意: 有一个长度为
n
n
n 的由
01
01
01 组成的字符串,你可以从中任选两个连续子串
s
1
s_1
s1 ,
s
2
s_2
s2 ,
f
(
s
i
)
f(s_i)
f(si) 代表
s
i
s_i
si 这个二进制串所代表的整数。求
f
(
s
1
)
∣
f
(
s
2
)
f(s_1) | f(s_2)
f(s1)∣f(s2) 最大为多少,输出其二进制形式。
思路: 求
o
r
or
or 值最大肯定是 原串 和 其中的一个子串的
o
r
or
or 值,由于题目中给出了数据的生成0 1是等概率随机的,所以找到二进制第一位1以及第一位1后面第一位0,因为要找最大的结果,所以只需要遍历这段长度,每次向右移动一位,然后进行或运算,找到最大的值即可。这里借鉴一大佬的写法。
代码:
//去除前导0
string Erase(string s){int idx =0;while(s[idx]=='0'&& idx < s.length()-1) idx ++;return s.substr(idx);}voidsolve(){int n;
string s;
cin >> n >> s;
s =Erase(s);
bitset<1000005>b1(s),b2(s);//二进制的容器,可以存储二进制位<长度> 将字符串转换到bitset,可以进行位运算操作
string ans = b1.to_string();for(int i =1; i <=50; i++){
ans =max(ans,(b1 |(b2 >> i)).to_string());//max字符串进行比较字符'1'要不'0'大}
cout <<Erase(ans)<< endl;}