A - Erasing Zeroes
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ll t;
cin>>t;
while(t--){
string s;
cin>>s;
ll f=0,t=s.size()-1;
for(ll i=0;i<s.size();i++){
while(f<s.size()&&s[f]=='0')
f++;
while(t>=0&&s[t]=='0')
t--;
}
if(f>t)
cout<<0<<endl;
else{
ll ans=0;
for(ll i=f;i<=t;i++){
if(s[i]=='0')
ans++;
}
cout<<ans<<endl;
}
}
}
B - National Project
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ll t;
cin>>t;
while(t--){
ll n,g,d;
cin>>n>>g>>d;
ll ans=(n+1)/2;
ans+=((ans+g-1)/g-1)*d;
ans=max(n,ans);
cout<<ans<<endl;
}
}
C - Perfect Keyboard
双向链表
#include<bits/stdc++.h>
using namespace std;
int pre[26],nex[26];
bool vis[26];
int main(){
int t;
cin>>t;
while(t--){
memset(pre,-1,sizeof(pre));
memset(nex,-1,sizeof(nex));
memset(vis,false,sizeof(vis));
string s;
cin>>s;
int head=s[0]-'a';
int cur=head;
vis[cur]=true;
bool flag=true;
for(int i=1;i<s.size();i++){
if(s[i]-'a'==nex[cur])
cur=nex[cur];
else if(s[i]-'a'==pre[cur])
cur=pre[cur];
else if(vis[s[i]-'a']){
flag=false;
break;
}
else if(nex[cur]==-1){
nex[cur]=s[i]-'a';
pre[s[i]-'a']=cur;
vis[s[i]-'a']=true;
cur=nex[cur];
}
else if(pre[cur]==-1){
pre[cur]=s[i]-'a';
nex[s[i]-'a']=cur;
vis[s[i]-'a']=true;
cur=pre[cur];
if(nex[cur]==head)
head=cur;
}
else{
flag=false;
break;
}
}
if(flag){
puts("YES");
cur=head;
while(cur!=-1){
cout<<char('a'+cur);
cur=nex[cur];
}
for(int i=0;i<26;i++){
if(!vis[i])
cout<<char('a'+i);
}
cout<<endl;
}
else
puts("NO");
}
return 0;
}
D - Fill The Bag
从小往大,没有就找比它大的最小的往下分解
可分解n,分解成若干二的次方数,为1的位加入集合,类似于快速幂?
然后从小到大凑,没有则从上往下分解,剩下的往上推
若最后集合为空,则yes,非空则no
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
ll t;
cin>>t;
while(t--){
ll n,m;
cin>>n>>m;
set<ll>se;
map<ll,ll>mp;
ll cur=1;
while(n){
if(n&1){
se.insert(cur);
}
n>>=1;
cur<<=1;
}
for(ll i=1;i<=m;i++){
ll x;
cin>>x;
mp[x]++;
}
ll ans=0;
for(ll i=1;i<=cur;i<<=1){
if(se.find(i)!=se.end()){
if(mp[i]){
se.erase(i);
mp[i]--;
}
else{
bool flag=false;
for(auto it:mp){
if(it.first>i&&it.second>0){
flag=true;
mp[it.first]--;
se.erase(i);
ll cur=it.first/2;
while(cur>=i){
mp[cur]++;
cur>>=1;
ans++;
}
break;
}
}
if(!flag){
break;
}
}
}
mp[i<<1]+=mp[i]/2;
mp[i]=mp[i]&1;
}
if(se.empty())
cout<<ans<<endl;
else
cout<<-1<<endl;
}
}
E - Erase Subsequences
若dp的结果只能是0或1,则可优化掉一维,原为0的dp值为-1,
原为1的dp值为j(设j维原先j的最后1维)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=410;
int dp[maxn][maxn];
int main(){
ll Case;
cin>>Case;
while(Case--){
string s,t;
cin>>s>>t;
bool flag=false;
for(int i=0;i<=t.size();i++){
string t1,t2;
for(int j=0;j<i;j++){
t1+=t[j];
}
for(int j=i;j<t.size();j++){
t2+=t[j];
}
memset(dp,-1,sizeof(dp));
dp[0][0]=0;
for(int k=0;k<s.size();k++){
for(int j=0;j<=t1.size();j++){
if(dp[k][j]>=0){
if(j<t1.size()&&t1[j]==s[k]){
dp[k+1][j+1]=max(dp[k+1][j+1],dp[k][j]);
}
if(dp[k][j]<t2.size()&&t2[dp[k][j]]==s[k]){
dp[k+1][j]=max(dp[k+1][j],dp[k][j]+1);
}
dp[k+1][j]=max(dp[k+1][j],dp[k][j]);
}
}
}
if(dp[s.size()][t1.size()]==t2.size()){
flag=true;
break;
}
}
if(flag)
puts("YES");
else
puts("NO");
}
}