没啥说的 签到题
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=4005;
int k;
int n,m,q,sum;
string sn[maxn],sm[maxn],ans[maxn];
map<string,int>mp,pd;
int main(){
cin>>k;
cin>>n;
int cnt=0;
for(int i=1;i<=n;i++)cin>>sn[i];
cin>>m;
for(int i=1;i<=m;i++)cin>>sm[i];
cin>>q;
for(int i=1;i<=q;i++){
string tt;
cin>>tt;
pd[tt]=1;
}
cnt=0;
for(int i=1;i<=n;i++){
if(!pd[sn[i]])continue;
++cnt;
ans[++sum]=sn[i];
mp[sn[i]]=1;
if(cnt==k)break;
}
cnt=0;
for(int i=1;i<=m;i++){
if(mp[sm[i]])continue;
if(pd[sm[i]]){
++cnt;
ans[++sum]=sm[i];
mp[sm[i]]=1;
}
if(cnt==k)break;
}
sort(ans+1,ans+1+sum);
cout<<sum<<endl;
for(int i=1;i<=sum;i++)
cout<<ans[i]<<endl;
return 0;
}
和题解思路大致都是一样的 但是就是差了一点点
不会做 看完题解不得不感叹题目出的真好
关键点在于想到把k场扔到后面自由排列 怎么摆放的不重要 重要的是每个是多少
后面k场的最多胜场就能知道了
前面转移的话就没啥难度了
不得不说这个题也很牛 有好几个点值得注意
相当于让 0 的权值为 S,1 的权值为 1,计算几个区间的权值大于等于 0
这样就变成了一个经典问题 :一个序列 求有多少个区间和大于等于0
维护前缀和 枚举右端点 看左边有多少个点的前缀和小于等于他 离散化之后树状数组维护就好