edu div2 183个人笔记(目前只补到D,后续可能会更新)
A:
链接: Problem - A - Codeforces
思路:
很简单的取余数,代码略。
B:
链接: Problem - B - Codeforces
思路:
看0、1的操作数有多少个,让左右两边铺满-,然后看中间,中间+的数量如果和2的数量一样,说明都能铺满,中间都变成-,否则把?从从左到右第一个+向右铺,从右到左第一个+向左铺。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+100;
int n,k;
int cnt0,cnt1,cnt2;
void solve(){cnt0=cnt1=cnt2=0;cin>>n>>k;string s,ans;cin>>s;if(n==k){for(int i=1;i<=n;i++)ans+='-';}else{for(auto c:s){if(c=='0') cnt0++;if(c=='1') cnt1++;if(c=='2') cnt2++;}for(int i=1;i<=n;i++){if(i<=cnt0||i>=n-cnt1+1)ans+='-';else if(i<=cnt0+cnt2||i>=n-cnt1-cnt2+1)ans+='?';elseans+='+';}}cout<<ans<<'\n';
} int main(){int t;cin>>t;while(t--){solve();}return 0;
}
C:
链接: Problem - C - Codeforces
思路:
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n;
string s;
void solve(){map<int,int>cnt;cin>>n;cin>>s;for(int i=-2*n;i<=2*n;i++)cnt[i]=-1;int x=0,cb=0;for(auto c:s){if(c=='b')cb++;}cnt[0]=0;x=n-2*cb;int ans=n;int sum=0;for(int i=1;i<=n;i++){if(s[i-1]=='b')sum++; cnt[i-2*sum]=i; if(cnt[i-2*sum-x]!=-1)ans=min(ans,i-cnt[i-2*sum-x]);}if(ans==n)ans=-1;cout<<ans<<'\n';
} int main(){int t;cin>>t;while(t--){solve();}return 0;
}
D:
链接: Problem - D - Codeforces
思路:
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=40;
const int M=3000;
int n,r;
int num[N];
ll dp[M][N];void solve(){cin>>n>>r;ll ans=-1;for(int i=0;i<=n;i++)for(int j=0;j<=n*(n-1)/2;j++)dp[j][i]=-1;dp[0][0]=0;for(int i=1;i<n;i++){for(int j=0;j<=n*(n-1)/2;j++){for(int k=0;k<i;k++){int cx=i-k;int cy=n-i;if(dp[j][k]==-1)continue;dp[j+cx*cy][i]=dp[j][k]+(1<<i);}}}for(int i=0;i<n;i++){if(dp[r][i]!=-1){ans=dp[r][i];}}if(ans==-1)cout<<0<<'\n';else{int l=0,r=0;int x=0;for(int i=1;i<n;i++){if((ans>>i)&1){num[i+1]=--l;}elsenum[i+1]=++r;x=min(x,num[i+1]);}for(int i=1;i<=n;i++)cout<<num[i]-x+1<<' ';cout<<'\n';}
}int main(){int t;cin>>t;while(t--){solve();}return 0;
}