Pinely Round 2 (Div. 1 + Div. 2)
A. Channel
分别假设给出的通告中上线的都是没有读过通告的人和读过通告的人,求出最多越多人数即可
void solve(){
cin >> n >> a >> q;
string s;
cin >> s;
if(a >= n){
cout << "YES\n";
return;
}
int ad = 0, sum = 0;
int mx = 0;
for(auto c : s){
if(c == '+') ad++, sum++;
else ad--;
mx = max(mx, ad);
}
if(a + mx >= n) cout << "YES\n";
else if(a + sum >= n) cout << "MAYBE\n";
else cout << "NO\n";
}
B. Split Sort
对于一个数 i , i ∈ [ 1 , n − 1 ] i,i\in [1,n-1] i,i∈[1,n−1],如果i+1在i的前面,那我们必须要把i提到i+1的前面,就必定有一次操作选的x=i+1,对答案的贡献加一,枚举所有 i , i ∈ [ 1 , n − 1 ] i,i\in[1,n-1] i,i∈[1,n−1]判断是否对答案有贡献即可
void solve(){
cin >> n;
for(int i = 1;i <= n;i++) cin >> p[i], pos[p[i]] = i;
int ans = 0;
for(int i = 1;i < n;i++){
if(pos[i+1] < pos[i]) ans++;
}
cout << ans << '\n';
}
C. MEX Repetition
这原本是一个长度为n包含[0,n]中n个数的数组,那[0,n]中剩下的一个没有被包含的数我们把它放到数组的最前方(下标为0的位置),展示的数时下标[1,n]范围内的数,每次操作实际上就是将数组向右旋转一次
void solve(){
cin >> n >> k;
vector<int>vis(n + 2, 0);
for(int i = 1;i <= n;i++) cin >> a[i], vis[a[i]] = 1;
for(int i = 0;i <= n;i++) if(!vis[i]){
a[0] = i;
break;
}
int st = 1, ed = n;
k %= (n + 1);
st = (1 + n + 1 - k) % (n + 1);
for(int i = 1;i <= n;i++){
cout << a[st] << ' ';
st++;
st %= (n + 1);
}
cout << '\n';
}
D. Two-Colored Dominoes
找到每对列相同的“LR”,分别赋为“WB”和“BW”,再找到每对行相同的“UD”,分别赋为“WB”和“BW”即可,若有任意的“LR“或”UD“找不到与其匹配的,则输出-1
void solve(){
cin >> n >> m;
for(int i = 1;i <= n;i++) cin >> mp[i], mp[i] = ' ' + mp[i];
for(int j = 1;j <= m;j++){
int last = 0;
for(int i = 1;i <= n;i++){
if(mp[i][j] == 'L'){
if(last){
mp[last][j] = 'B';
mp[last][j+1] = 'W';
mp[i][j] = 'W';
mp[i][j+1] = 'B';
last = 0;
}else{
last = i;
}
}
}
if(last){
cout << "-1\n";
return;
}
}
for(int i = 1;i <= n;i++){
int last = 0;
for(int j = 1;j <= m;j++){
if(mp[i][j] == 'U'){
if(last){
mp[i][last] = 'B';
mp[i+1][last] = 'W';
mp[i][j] = 'W';
mp[i+1][j] = 'B';
last = 0;
}else{
last = j;
}
}
}
if(last){
cout << "-1\n";
return;
}
}
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
cout << mp[i][j];
}
cout << '\n';
}
}