文章目录
题目
A. Angry Students
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=110;
char s[MAXN];
int main(){
ll t;
scanf("%lld",&t);
while(t--){
ll n;
scanf("%lld",&n);
getchar();
scanf("%s",s);
ll ans=0;
ll cur=0;
bool flag=false;
for(int i=0;i<n;i++){
if(s[i]=='A'){
flag=true;
cur=0;
}
else if(flag){
cur++;
ans=max(cur,ans);
}
}
printf("%lld\n",ans);
}
}
B. Hyperset
很巧妙的一道题,因为可通过任意两个字符串确定第三个字符串,因此用map存一下所有字符串的个数n2枚举即可,注意string的用法,以开始默认为空
#include<bits/stdc++.h>
using namespace std;
const int maxn=1500+10;
string s[maxn];
unordered_map<string,int>mp;
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
cin>>s[i];
mp[s[i]]++;
}
int ans=0;
for(int i=1;i<n;i++){
for(int j=i+1;j<=n;j++){
string st;
for(int p=0;p<k;p++){
if(s[i][p]==s[j][p])
st+=s[i][p];
else if(s[i][p]!='S'&&s[j][p]!='S')
st+='S';
else if(s[i][p]!='E'&&s[j][p]!='E')
st+='E';
else
st+='T';
}
if(mp.count(st))
ans+=mp[st];
}
}
printf("%d\n",ans/3);
return 0;
}
C. Garland
dp,类似背包问题,第二第三维表示到当点位置消耗奇数与偶数的个数,cnt为到当前位置总计0
的个数
#include<bits/stdc++.h>
#define de(x) cout<<#x<<" = "<<x<<endl;
using namespace std;
const int maxn=100+10;
int dp[maxn][maxn][maxn][2];
int a[maxn];
const int INF=0x3f3f3f3f;
int main(){
int n;
scanf("%d",&n);
int odd=n/2,even=n/2;
odd+=(n&1);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(a[i]&1)
odd--;
else if(a[i]!=0)
even--;
}
int cnt=0;
for(int i=1;i<=n;i++){
if(!a[i]){
cnt++;
for(int j=0;j<=cnt&&j<=odd;j++){
int k=cnt-j;
if(k>even)continue;
if(k)
dp[i][j][k][0]=min(dp[i-1][j][k-1][1]+1,dp[i-1][j][k-1][0]);
else
dp[i][j][k][0]=INF;
if(j)
dp[i][j][k][1]=min(dp[i-1][j-1][k][0]+1,dp[i-1][j-1][k][1]);
else
dp[i][j][k][1]=INF;
}
}
else{
for(int j=0;j<=cnt&&j<=odd;j++){
int k=cnt-j;
if(k>even)continue;
if(a[i]&1){
dp[i][j][k][1]=min(dp[i-1][j][k][0]+1,dp[i-1][j][k][1]);
dp[i][j][k][0]=INF;
}
else{
dp[i][j][k][0]=min(dp[i-1][j][k][1]+1,dp[i-1][j][k][0]);
dp[i][j][k][1]=INF;
}
}
}
}
printf("%d\n",min(dp[n][odd][even][0],dp[n][odd][even][1]));
return 0;
}
D. Numbers on Tree
n2合并vector
随后补nlogn平衡树的合并吧
这题是个不错的平衡树练习题
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e3+10;
int head[MAXN];
struct Edge{
int v,next;
}e[MAXN];
int ord[MAXN];
int cnt;
const int INF=0x3f3f3f3f;
int f[MAXN],c[MAXN],sz[MAXN];
void add(int u,int v){
e[cnt].next=head[u];
e[cnt].v=v;
head[u]=cnt++;
}
vector<int> dfs(int u){
vector<int>res;
sz[u]=1;
int cur=0;
if(u&&cur==c[u])
res.push_back(u);
for(int i=head[u];~i;i=e[i].next){
int v=e[i].v;
vector<int>tmp=dfs(v);
sz[u]+=sz[v];
for(int i=0;i<tmp.size();i++){
res.push_back(tmp[i]);
cur++;
if(u&&cur==c[u])
res.push_back(u);
}
}
if(u&&sz[u]<=c[u]){
puts("NO");
exit(0);
}
//cout<<res.size()<<endl;
return res;
}
int main(){
memset(head,-1,sizeof(head));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&f[i],&c[i]);
add(f[i],i);
}
vector<int>ans=dfs(0);
for(int i=0;i<ans.size();i++){
ord[ans[i]]=i+1;
//cout<<ans[i]<<endl;
}
puts("YES");
for(int i=1;i<=n;i++){
printf("%d%c",ord[i],i==n?'\n':' ');
}
return 0;
}
E1. Madhouse (Easy version)
#include<bits/stdc++.h>
using namespace std;
const int maxn=110;
unordered_map<string,int>mp[maxn];
int cnt[30];
int main(){
string ans;
int n;
scanf("%d",&n);
if(n==1){
puts("? 1 1");
fflush(stdout);
cin>>ans;
cout<<"! "<<ans<<endl;
}
else{
printf("? 1 %d\n",n);
fflush(stdout);
string temp;
for(int i=0;i<n*(n+1)/2;i++){
cin>>temp;
sort(temp.begin(),temp.end());
mp[temp.size()][temp]++;
}
printf("? 2 %d\n",n);
fflush(stdout);
for(int i=0;i<n*(n-1)/2;i++){
cin>>temp;
sort(temp.begin(),temp.end());
mp[temp.size()][temp]--;
}
for(int i=1;i<=n;i++){
for(auto it=mp[i].begin();it!=mp[i].end();it++){
if(it->second){
memset(cnt,0,sizeof(cnt));
for(int j=0;j<ans.size();j++){
cnt[ans[j]-'a']++;
}
for(int j=0;j<it->first.size();j++){
if(cnt[it->first[j]-'a']==0){
ans+=it->first[j];
break;
}
cnt[it->first[j]-'a']--;
}
}
}
}
printf("! ");
cout<<ans<<endl;
}
}
E2. Madhouse (Hard version)
#include<bits/stdc++.h>
using namespace std;
const int maxn=110;
unordered_map<string,int>mp[maxn];
int cnt[30];
int num[30][maxn];
string solve(int n){
string ans;
printf("? 1 %d\n",n);
fflush(stdout);
string temp;
for(int i=0;i<n*(n+1)/2;i++){
cin>>temp;
sort(temp.begin(),temp.end());
mp[temp.size()][temp]++;
}
printf("? 2 %d\n",n);
fflush(stdout);
for(int i=0;i<n*(n-1)/2;i++){
cin>>temp;
sort(temp.begin(),temp.end());
mp[temp.size()][temp]--;
}
for(int i=1;i<=n;i++){
for(auto it=mp[i].begin();it!=mp[i].end();it++){
if(it->second){
memset(cnt,0,sizeof(cnt));
for(int j=0;j<ans.size();j++){
cnt[ans[j]-'a']++;
}
for(int j=0;j<it->first.size();j++){
if(cnt[it->first[j]-'a']==0){
ans+=it->first[j];
break;
}
cnt[it->first[j]-'a']--;
}
}
}
}
return ans;
}
int main(){
string ans;
int n;
scanf("%d",&n);
if(n==1){
puts("? 1 1");
fflush(stdout);
cin>>ans;
cout<<"! "<<ans<<endl;
}
else if(n==2){
char ch;
puts("? 1 1");
fflush(stdout);
cin>>ch;
ans+=ch;
puts("? 2 2");
fflush(stdout);
cin>>ch;
ans+=ch;
cout<<"! "<<ans<<endl;
}
else{
string halfans;
ans=solve((n+1)/2);
printf("? 1 %d\n",n);
fflush(stdout);
for(int i=0;i<n*(n+1)/2;i++){
string temp;
cin>>temp;
for(int j=0;j<temp.size();j++){
num[temp[j]-'a'][temp.size()]++;
}
}
for(int i=0;i<=n/2;i++){
for(int j=0;j<26;j++){
int Num=num[j][1]-(num[j][i+1]-num[j][i]);
for(int k=0;k<i;k++){
if(ans[k]-'a'==j)
Num--;
}
for(int k=0;k<halfans.size();k++){
if(halfans[k]-'a'==j)
Num--;
}
if(Num){
halfans+=('a'+j);
break;
}
}
}
for(int i=halfans.size()-1;i>=0;i--){
ans+=halfans[i];
}
printf("! ");
cout<<ans<<endl;
}
}