Educational Codeforces Round 153 (Rated for Div. 2)
A. Not a Substring
只有” ( ) () ()“这种情况无解,否则判断给出的序列是否有两个连续的相同括号,有则构造n个" ( ) () ()",否则构造n层嵌套括号
void solve(){
string s;
cin >> s;
n = s.size();
if(s == "()"){
cout << "NO\n";
return;
}
cout << "YES\n";
bool f = false;
for(int i = 0;i < n -1;i++) if(s[i] == s[i+1]) f = true;
if(f){
for(int i = 1;i <= 2 * n;i++) {
if(i & 1) cout << '(';
else cout << ')';
}
}else{
for(int i = 1;i <= n;i++) cout << '(';
for(int i = 1;i <= n;i++) cout << ')';
}
cout << '\n';
}
B. Fancy Coins
先分别使用所有大面值和小面值的普通硬币,如果还不够则再先使用大面值花式硬币,若还不够要判断此时是否能收回之前使用的一元普通硬币从而只用再消耗一枚k元花式硬币,若不行最后再使用一元花式硬币
void solve(){
cin >> m >> k >> a1 >> ak;
int ans = 0;
if(ak * k > m){
m %= k;
m = max(0ll, m - a1);
cout << m << '\n';
return;
}
m -= ak * k;
if(m <= a1){
cout << "0\n";
return;
}
m -= a1;
int ck = m / k;
ans += ck;
m -= ck * k;
if(m && a1 + m >= k) ans++;
else ans += m;
cout << ans << '\n';
}
C. Game on Permutation
做P/N分析即可
对于Alice:
若一开始放在从第一个数开始递减的一段区间,都是必败的。
从这个区间后的第一个数开始往后推:递减区间后的第一个数只能被移动到必败态,所以该位置是必胜态,继续往后分析即可
- 只能移动到必败态的是必胜态
- 能移动到必胜态的是必败态
- 不能移动的是必败态
往后递推时用一个树状数组记录前方是否有比当前的数小的必胜态即可
int w[N];
int lowbit(int x){
return x & -x;
}
void addw(int x, int v){
while(x <= n){
w[x] += v;
x += lowbit(x);
}
}
int getw(int x){
int ret = 0;
while(x > 0){
ret += w[x];
x -= lowbit(x);
}
return ret;
}
void init(){
for(int i = 1;i <= n;i++) w[i] = 0;
}
void solve(){
cin >> n;
init();
for(int i = 1;i <= n;i++) cin >> a[i];
int mn = a[1];
int p = n + 1;
for(int i = 2;i <= n;i++){
if(a[i] > a[i-1]){
p = i;
break;
}
mn = min(a[i], mn);
}
int ans = 0;
for(int i = p;i <= n;i++){
if(getw(a[i]) == 0 && a[i] > mn) addw(a[i], 1), ans++;
mn = min(mn, a[i]);
}
cout << ans << '\n';
}