20240823

赛时得分

题目 A B C D 总分 排名 比例
满分 100 100 100 100 400 153 100%
得分 60 50 30 20 160 91 59.5%

A. 粉刷匠(60/100)

\(\text{30pts}\) 部分考虑直接 \(\mathcal{O}(nm)\) 直接枚举,开一个结构体存 set 进行维护即可。

\(\text{60pts}\) 有点乱搞成分在的。考虑把每个颜色左右边界存一下,但显然是可能不连续的。但显然 OI 是骗分游戏,精度上看误差不大。

#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
#define minn first
#define maxn second
using namespace std;
const int N=1e5+1; 
ll n,m,a,b,c,cnt,ans=1,befl,befr,maxc=-1,maxx=-1;
map<ll,pair<ll,ll> > mp;
struct lhm
{
	set<ll> s;
}col[N];
bool ok;
int main()
{
	freopen("paint.in","r",stdin);
	freopen("paint.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	if(n<=100 and m<=100)
	{
		for(int i=1;i<=n;i++)
		{
			cin>>a>>b>>c;
			for(int j=1;j<=m;j++)
			{
				if(j>=a and j<=b) col[j].s.insert(c);
				else col[j].s.insert(0);
			}
		}
		for(int i=1;i<=m;i++)
		{
			ll len=col[i].s.size();
			maxx=max(maxx,len);
		}
		cout<<maxx;
		return 0;
	}
	for(int i=1;i<=n;i++)
	{
		cin>>a>>b>>c;
		if(i==1) befl=a,befr=b;
		befl=max(befl,a),befr=min(befr,b);
		maxc=max(maxc,c);
		if(!mp[c].minn and !mp[c].maxn) mp[c].minn=a,mp[c].maxn=b;
		else mp[c].minn=min(a,mp[c].minn),mp[c].maxn=max(b,mp[c].maxn);
	}
	for(int j=1;j<=m;j++)
	{
		if(j>=befl and j<=befr) cnt=0;
		else cnt=1;
		for(int i=1;i<=maxc;i++)
		{
			if(mp[i].minn==0) continue;
			if(j<mp[i].minn or j>mp[i].maxn) continue;
			cnt++;
		}
		ans=max(ans,cnt);
	}
	cout<<ans;
	return 0;
}

B. 第 k 小(50/100)

\(\text{30%}\) 得分做法,直接暴力扔进一个 set 中。

\(\text{50%}\) 得分做法,考虑 \(k\leq n\) 的部分分,我们赌一波缩小范围,只扫到 \(\min(n/m,2\times\sqrt{k})\) 即可,这样在减小循环次数的同时也可以保证答案正确性。

#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
const int N=4e4+1;
ll n,m,k,a[N],b[N],tar;
multiset<ll> s;
int main()
{
	freopen("kth.in","r",stdin);
	freopen("kth.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m>>k;
	tar=((ll)sqrt(k))*2+1;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=m;i++) cin>>b[i];
	if(n<=500 and m<=500)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++) s.insert(a[i]+b[j]);
		}
	}
	else
	{
		for(int i=1;i<=min(n,tar);i++)
		{
			for(int j=1;j<=min(m,tar);j++) s.insert(a[i]+b[j]);
		}
	}
	auto it=s.begin();
	advance(it,k-1);
	cout<<*it;
	return 0;
}

C. 比赛(30/100)

\(\text{30%}\) 得分做法,考虑直接 next_permutation 枚举全排列,然后直接加权概率即可。

#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
ll n,m,pos[5001];
struct lhm
{
	ll num;
	double val[5001];
}a[11];
double ans,cnt;
int main()
{
	freopen("contest.in","r",stdin);
	freopen("contest.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=max(n,m);i++) pos[i]=i;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++) cin>>a[i].val[j];
	}
	if(n==m)
	{
		do
		{
			cnt=0;
			for(int i=1;i<=n;i++) cnt+=a[i].val[pos[i]];
			ans=max(ans,cnt);
		}while(next_permutation(pos+1,pos+n+1));
		printf("%.5lf",ans);
	}
	return 0;
}

D. 可爱宝宝拍照(20/100)

乱搞过的 \(20\) 分。没啥思路。

#include<bits/stdc++.h>
#define Std_Maker lhm
#define ll long long
using namespace std;
const int N=1e5+1;
ll n,m,a,b,l,r,cnt;
struct lhm
{
	ll a,b,len;
}f[N];
bool cmp(lhm x,lhm y)
{
	if(x.len==y.len)
	{
		if(x.a==y.a) return x.b<y.b;
		return x.a<y.a;
	}
	return x.len<y.len;
}
set<pair<ll,ll> > s;
int main()
{
	freopen("photo.in","r",stdin);
	freopen("photo.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>f[i].a>>f[i].b;
		f[i].len=f[i].b-f[i].a+1;
	}
	sort(f+1,f+m+1,cmp);
	s.insert({f[1].a,f[1].b});
	for(int i=2;i<=m;i++)
	{
		cnt=0;
		a=f[i].a,b=f[i].b;
		for(auto j:s)
		{
			l=j.first,r=j.second;
			if(a<=l and b>=r) cnt++;
		}
		if(cnt==0) s.insert({a,b});
		if(cnt>1)
		{
			cout<<-1;
			return 0;
		}
	}
	cout<<s.size();
	return 0;
}
posted @ 2024-08-23 14:24  Lithium_Chestnut  阅读(8)  评论(0)    收藏  举报