2022 MetaCamp程序设计大赛线上初赛1

没啥说的 签到题

#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

维护前缀和 枚举右端点 看左边有多少个点的前缀和小于等于他 离散化之后树状数组维护就好

posted @ 2022-08-07 18:09  wzx_believer  阅读(138)  评论(0编辑  收藏  举报