山东理工大学第十五届ACM程序设计竞赛 R - Zyn的超能力

Description

Zyn 需要能量提高自己的超能力,有两种能量存在:超级能量和小能量。对于超级能量,Zyn 绝对不可以错过,而且努力的 Zyn 希望得到更多的小能量。

但是 Zyn 每天最多可以获得 k 次能量,而且每个能量都会在第 xi​ 天后消失,Zyn 希望你可以帮助他求出得到的小能量的最多数量。

Input

第一行包含三个正整数 n,m,k (1≤n,m≤106,1≤k≤107) 表示超级能量,小能量和每天最多可以获得能量的个数。

第二行包含 n 个整数,表示第 i 个超级能量会在第 xi​ (0≤xi​≤107) 天消失。

第三行包含 m 个整数,表示第 i 个小能量会在第 xi​ (0≤xi​≤107) 天消失。

Output

如果不能获得全部超级能量,输出"Zyn!"(不含引号),否则输出可以获得的最多的小能量的数量。

Sample

Input 

3 4 2
0 2 3
1 1 2 5

5 3 2
0 0 0 1 1
1 1 2

Output 

4

Zyn!

Hint

题目样例为两组,由于 OJ 不支持多样例所以用回车分隔开。

样例一:可以在 44 天内获得所有小能量,

  • 第 00 天:22 个超级能量
  • 第 11 天:22 个小能量
  • 第 22 天:11 个超级能量 + 11 个小能量
  • 第 33 天:11 个小能量

总共获得 44 个小能量(33 个超级能量全部获得)

样例二:没用任何一种方法可以获得全部超级能量,输出"Zyn!"(不含引号)

考试时的思路完全错了,想得就是从前向后遍历,如果今天的超近能量大于k,则判断一下ans+k与今日超级能量的大小关系;

错误代码(当然也犯了一个致命错误,应该从0开始)

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+100;
#define endl '\n'
#define ll long long
int n,m,k;
int supper[N],small[N];
int cnt;
int cnt1[N];
int cnt2[N];
int ans;
int M;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<=n;i++)
	{
	scanf("%d",&supper[i]);
	cnt1[supper[i]]++;
	M=max(M,supper[i]);
	}
	for(int i=1;i<=m;i++)
	{
	scanf("%d",&small[i]);
	cnt2[small[i]]++;
	M=max(M,small[i]);	
	}
	while(1)
	{
	if(cnt>M)
	break;
	int num=k;
	if(cnt1[cnt]>k)
	{
	if(cnt1[cnt]>k+ans)
	{
	printf("Zyn!");
	return 0;
	}
	else
	{
	 if(ans>=cnt1[cnt])
	 ans-=cnt1[cnt];
	 else 
	 {
	 ans=0;
	 num=num+ans-cnt1[cnt];
	 }
	}
	}
	else
	num-=cnt1[cnt];
	if(num>=cnt2[cnt])
	{
		num-=cnt2[cnt];
		ans+=cnt2[cnt];
	}
	else
	ans+=num;
	cnt++;
	}
	printf("%d\n",ans);
	return 0;
}

根据截止时间的性质,按照截止时间从大到小的顺序依次枚举超级能量,判定每天剩余小能量的 数量,然后根据当天小能量的数量枚举可能的最大数量

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;
#define inf 0x3f3f3f3f
int  a[N],b[N];
int n,m,k;
int maxa,maxb;
int cnt;
int ans;
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        a[x]++;
        maxa=max(maxa,x);
    }
    for(int i=0;i<m;i++)
    {
        int x;
        cin>>x;
        b[x]++;
        maxb=max(maxb,x);
    }
    for(int i=maxa;i>=0;i--)
    {
        if(a[i]>k)
        {
         cnt+=a[i]-k;
         a[i]=k;
        }
        else if(a[i]<k)
        {
            if(cnt>=k-a[i])
            {
                cnt-=(k-a[i]);
                a[i]=k;
            }
        }
    }
    if(cnt)//没有拿全超级能量
    {
        cout<<"Zyn!";
        return 0;
    }
    cnt=0;
    for(int i=maxb;i>=0;i--)
    {
       b[i]+=cnt;
       cnt=0;
       if(b[i])
       {
         int can=k-a[i];
         if(can>=b[i])
         {
            ans+=b[i];
            b[i]=0;
         }
         else
         {
            ans+=can;
            b[i]-=can;
            cnt=b[i];
            b[i]=0;
         }
       } 
    }
    cout<<ans<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ACM-ICPC(国际大学生程序设计竞赛)是一项全球性的大学生程序设计比赛,每年吸引来自世界各地的顶尖大学代表队参与。ACM-ICPC竞赛的核心内容是团队编程和问题解决能力。 首先,ACM-ICPC竞赛对参赛选手的编程能力要求很高。参赛队伍需要在规定的时间内解决一系列的算法问题,这些问题常常包含复杂的数据结构和算法,要求选手在有限的时间内设计和实现高效的程序。 其次,ACM-ICPC竞赛强调团队协作。每个队伍由三名选手组成,他们需要分工合作,保持良好的沟通与协调,共同解决问题。团队成员需要相互理解、相互信任,快速地协商和决策,同时要保持高效的任务分配和时间管理。 此外,ACM-ICPC竞赛也需要选手具备良好的问题解决能力。这些问题往往是实际应用或理论推导相关的,选手需要从数学、计算机科学和算法等多个角度出发,找到最佳解决方案。在面对问题时,选手需要对问题进行分析、抽象和建模,运用各种算法和数据结构进行解决。 对于参赛选手来说,ACM-ICPC提供了一个学习与交流的平台。在比赛中,选手可以接触到不同国家和地区的优秀程序设计人才,学习他们的思维方式和编程技巧。同时,ACM-ICPC还举办了一系列的培训和研讨会,让选手有机会深入了解计算机科学和算法领域最新的研究成果。 总之,ACM-ICPC国际大学生程序设计竞赛是一个挑战性与学习性兼具的比赛。它要求选手具备扎实的编程技能、团队合作能力和问题解决能力。参与此竞赛不仅可以锻炼自己的编程能力,还能与全球的顶尖程序设计人才进行交流,拓宽自己的视野和思维方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值