A. Rook
签到
棋子所在的行列全部输出(只输出打叉部分,不包含自己)
B. YetnotherrokenKeoard
输入一串字符串,如果是'B'删除最后一个大写字母,如果是'b'删除最后一个小写字母,没有就不执行。
因为一直在删除最后一个,所以可以开两个栈维护一下大小写字母的下标。
#include <bits/stdc++.h>
//#define int long long
#define fr first
#define se second
#define endl '\n'
using namespace std;
const int N=1e6+5;
string s;
stack<int>low,up;
bitset<N>del;
//大小写的idx
//'b' 删除最后一个小写字母
//'B' 删除最后一个大写字母
void solve(){
cin>>s;
for(int i=0;i<s.length();++i){
if(s[i]=='B'){
if(up.size()){
del[up.top()]=true;
up.pop();
}
}else if(s[i]=='b'){
if(low.size()){
del[low.top()]=true;
low.pop();
}
}else if(s[i]>='A' and s[i]<='Z'){
up.push(i);
}else if(s[i]>='a' and s[i]<='z'){
low.push(i);
}
}
for(int i=0;i<s.length();++i)
if(s[i]=='B' or s[i]=='b')continue;
else if(!del[i])cout<<s[i];
cout<<endl;
}
void init(){
while(low.size())low.pop();
while(up.size())up.pop();
del.reset();
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr);
int t;
cin>>t;
while(t--)solve(),init();
return 0;
}
补题:C. Removal of Unattractive Pairs
假设现在有10个字符,其中a只出现了2次,那么剩下的8个字符都可以用来和a相邻匹配来删除a。(不管排列顺序如何,肯定能删除a 8次)
那么累计一下某个字符不能被全部删除。(如果某个字符的数量多于总字符的一半,那么多出来的部分必然删不掉)
#include <bits/stdc++.h>
//#define int long long
#define fr first
#define se second
#define endl '\n'
using namespace std;
int n,ans,cnt[200];
string s;
void solve(){
cin>>n>>s;
for(int i=0;i<n;++i)cnt[s[i]]++;
for(char i='a';i<='z';++i)
ans=max(ans,cnt[i]-(n-cnt[i]));//cnt[i]可以被剩下的n-cnt[i]来删除
if(n&1 and !ans)ans++;//特判奇数情况,ans至少为1
cout<<ans<<endl;
}
void init(){
for(char i='a';i<='z';++i)cnt[i]=0;
ans=0;
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr);
int t;
cin>>t;
while(t--)solve(),init();
return 0;
}
总结
前两题18分钟快速拿下。C题开始钻牛角尖,钻了2个小时超时一次WA一次。
下次注意,思路如果无法快速实现在磨磨蹭蹭敲代码,或者一样的代码反复删了又写,很有可能本蒟蒻脑就陷入死循环了。
通过数学公式或者状态分析之类的先证明算法是正确的再敲代码(除非显然正确),如果证明不出来就换思路,或者干脆这题就不做了看下一题。