Educational Codeforces Round 160 (Rated for Div. 2)
Educational Codeforces Round 160 (Rated for Div. 2)
A. Rating Increase
题意:给定一个由数字字符组成的字符串,且无前导零,将其分割成ab两部分,b不能有前导零,拆分后的数字a是否可以严格小于数字b
思路:数据很小,可以暴力拆分,数字|字符串操作均可。这里是尽可能将数字靠前分割来判断分割后的两字符串。
AC code:
void solve(){
string s; cin >> s;
string cnt = "";
int pos;
cnt += s[0];
for(int i = 1; i < s.size(); i ++){
if(s[i] != '0'){
pos = i;
break;
}
cnt += s[i];
}
string tt = "";
for(int i = pos; i < s.size(); i ++)
tt += s[i];
if(tt == cnt || tt.size() < cnt.size() || tt.size() == cnt.size() && tt < cnt){
cout << "-1" << endl;
return;
}
cout << cnt << " "<< tt << endl;
}
B. Swap and Delete
题意:给定01二进制字符串s,现在有两种操作:
- 删除任一字符,成本为1;
- 交换相邻的任意字符,成本为0;
将操作后的字符串定为t,字符串t与原字符串s左对齐对每一位进行比较,若均不相等则t为好字符串,空字符串默认为好字符串;
求操作的最小成本。
思路:首先分别记录01字符的数量,然后遍历字符串s,遍历时需要记录走过的可以交换的0和1,若前方有可交换的字符时,就减去该字符,否则查看剩余01字符,选择交换然后同时减去两字符并将当前字符记录到交换字符中。
AC code:
void solve(){
string s; cin >> s;
n = s.size();
int zero = 0, one = 0;
for(int i = 0; i < n; i ++){
if(s[i] == '0') zero ++;
else one ++;
}
int cnt_0 = 0, cnt_1 = 0;
for(int i = 0; i < n; i ++){
if(s[i] == '0'){
if(cnt_1){
cnt_1 --;
}else if(one){
one --;
zero --;
cnt_0 ++;
}else{
cout << n - i << endl;
return;
}
}else{
if(cnt_0){
cnt_0 --;
}else if(zero){
one --;
zero --;
cnt_1 ++;
}else{
cout << n - i << endl;
return;
}
}
}
cout << 0 << endl;
}
C. Game with Multiset
题意:最初有一个空集,需要处理两种操作:
- 在集合中添加 2 x 2^x 2x
- 查询是否存在集合中的和为v
思路:位运算,每次添加的元素均为二进制的x位,记录二进制中存入的位,当查询时只需要从后往前遍历二进制数,看当前位存储的是否足够,不够就*2累加到下一位尝试减去。
AC code:
map<int, int> mp, cnt;
void solve(){
cin >> n;
for(int i = 0; i < n; i ++){
int t, v; cin >> t >> v;
if(t == 1){
mp[v] ++;
}else{
int now = 0;
for(int i = 30; i >= 0; i --){
int pos = v >> i & 1;
pos += now * 2;
if(mp[i] < pos) now = pos - mp[i];
else now = 0;
}
if(now) cout << "NO" << endl;
else cout << "YES" << endl;
}
}
}