2021 CCPC新疆省赛补题部分题解

A. balloon

题目大意:
潇湘有小孩和mm的气球。
今天下课后,我的朋友们要去抓这些气球。每个气球在墙上都有一定的高度。只有当孩子跳起来时,他们的手所能达到的高度大于或等于气球的高度,孩子才能拿起气球。
为了公平起见,老师让跳得低的孩子先摘,跳得高的孩子再摘。
孩子们是非常贪心的,每个孩子在摘气球的时候都会摘下所有他能摘到的气球。
巧合的是,孩子们在跳起来的时候可以达到不同的高度,这样同样高度的孩子在跳起来之后就不会有纠纷了。
在这里插入图片描述
简单的模拟,直接上代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e5+10;
typedef pair<int,int> PII;
int b[N];
PII a[N];
int n,m;
int res[N];
int main(){
	memset(res,0,sizeof res);
    scanf ("%d%d",&n,&m);
    for (int i=1;i<=n;i++) 
	{
		int x;
		scanf ("%d",&x);
		a[i] = {x,i};
	}
	
    for (int i=1;i<=m;i++) scanf ("%d",&b[i]);
    
    sort(a+1,a+1+n);
    sort(b+1,b+1+m);
    int j=1;
    for (int i=1;i<=n;i++)
    {
    	int h = a[i].first,cnt=0;
    	while (h>=b[j]&&j<=m)
    	{
    		cnt++;
    		j++;
		}
		res[a[i].second] = cnt;
	}
	for (int i=1;i<=n;i++)
	   printf ("%d\n",res[i]);
	return 0;
}

B. sophistry

题目大意:

在小K的QQ群里,小T总是变得越来越奇怪。
小T将在小组发言n天,小K的愤怒值m。
小T每天都有一个能力值,第i天的能力值是ai
每一天,小T都会选择是否嘲笑小K。如果小T选择在第2天嘲笑小K,小K就会被a2伤害
我在此基础上,如果小T的能力值ai我​
超过了小K的愤怒值m,小K将勃然大怒,并禁止小T在d天内使用。也就是说,在i+1, i+2,…min (i + n) i + 1, + 2,…,min (i + d, n)天,肖T将被禁止。
现在,肖T想把对肖K的伤害最大化,但是肖T太坏了解决不了这个问题,所以他找到了你。希望你能帮他解决这个问题。你只需要找出Xiao T对Xiao K造成的最大损害。
题目一看就是决策问题,动态规划,每天小T都会决策是否嘲笑小K,而限制条件是当ai>m时,小K会产生不产生价值的缓冲期,这样后面会有一些状态不能再决策,当时做的时候,另一个队员发现每天都是相互独立的,如果倒叙转移的话,就可以简化了。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
long long dp[N],a[N];

int main()
{
    int n,d,m;
    cin >> n >> d >> m;
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    for(int i=n;i>=1;i--)
    {
        if(a[i]<=m)dp[i]=dp[i+1]+a[i];
        else
            dp[i]=max(dp[i+1+d]+a[i],dp[i+1]);
    }
    cout <<dp[1];
}

D. maxsum

题目大意:
给你一个数组,让你求前w大的子数组和。
一个简单的贪心,很容易想到所有方案都被枚举

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
typedef long long LL;
const int N = 1e5+10;
int a[N];
struct Node{
	int l,r;
	LL sum;
	bool operator <(const Node &t)const
	{
		return sum<t.sum;
	}
};
priority_queue<Node> p;
map<pair<int,int>,bool> mh;
int n,w;
int main(){
	LL s=0;
	scanf ("%d%d",&n,&w);
	for (int i=1;i<=n;i++)
	{
		scanf ("%d",&a[i]);
		s+=a[i];
	}
	p.push({1,n,s});
	while (w--)
	{
		auto t = p.top();
		p.pop();
		printf ("%lld ",t.sum);
		int l = t.l,r = t.r;
		if (!mh[{l+1,r}])
		   p.push({l+1,r,t.sum-a[l]});
		if (!mh[{l,r-1}])
		p.push({l,r-1,t.sum-a[r]});
		mh[{l,r-1}] = mh[{l+1,r}]= true;
	}
	return 0;
}

E. array

题目大意:

在这里插入图片描述
题意言简意赅,该题的重点是发现输入描述的范围,发现a,b数组里大多数都是零。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 2e5+10;
int a[N],b[N],res[N];
int c[N],d[N],cnt1=0,mx=-1,cnt2=0;
int main()
{
   int n;
    scanf ("%d",&n);
    for (int i=0;i<n;i++)
    {
        scanf ("%d",&a[i]);
        if (a[i]!=0)
           c[cnt1++] = i;
        mx = max(mx,a[i]);
    }
    for (int i=0;i<n;i++)
    {
        scanf ("%d",&b[i]);
        if (b[i]!=0)
            d[cnt2++] = i;
        mx = max(mx,b[i]);
    }
    for (int i=0;i<cnt1;i++)
    {
        for (int j=0;j<cnt2;j++)
        {
           res[(c[i]+d[j])%n] = max(res[(c[i]+d[j])%n],a[c[i]]+b[d[j]]);
        }
    }
    for (int i=0;i<n;i++)
    {
        if (i!=n-1)
            printf ("%d ",max(res[i],mx));
        else
            printf("%d\n",max(res[i],mx));
    }
  return 0;
}

这次比赛发现很多题并不是不会,而是需要去不断尝试,发现。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值