贪心-cf-C-塞尔逵传说

贪心-cf-C-塞尔逵传说

题干
C. 赛尔逵传说
time limit per test1.0 s
memory limit per test256 MB
inputstandard input
outputstandard output
天天最近买了一台思维吃来玩赛尔逵传说。

赛尔逵传说需要玩家扮演近侍骑士森克从恶魔噶里嗷的手里救下赛尔逵公主。但是救出公主的路途异常艰险,噶里嗷在去城堡的路途上设置了 n 只怪兽来阻挡森克,这 n 只怪兽分别编号从 1 到 n。其中第 i 只怪兽血量为 di 攻击力为 xi。

已知森克的攻击力为 k,他将按顺序轮流与这些怪兽进行若干次回合制战斗。在回合制战斗中,被攻击者会损失攻击者攻击力大小的血量,当被攻击者血量掉到 0 及以下就会立即死亡。每个回合都由森克主动对怪兽发起一次攻击(森克始终先手攻击怪兽),如果怪兽尚未死亡,那么它在本回合就会立即反击森克一次,即森克被攻击后损失该只怪兽攻击力大小的血量,如此循环直到其中某一战斗方死亡为止。

森克为了确保能救出公主,提前准备了 c 份"力量炖水果",每份"力量炖水果"都可以在瞬间吃下并使森克本回合临时增加 k 点攻击力,而且一回合内森克可以连续吃许多份"力量炖水果"。请问,森克如果想要救下赛尔逵公主的话,最少需要消耗多少血量呢?

Input
输入共 n+1 行,第一行输入三个正整数 n,k,c (1≤n≤105,1≤k,c≤106) 由空格间隔开,分别表示怪物数 n,森克的攻击力 k 与他烹饪的"力量炖水果"数量 c。

接下来 n 行,第 i 行输入两个正整数 di 和 xi (1≤di,xi≤106),分别描述第 i 只怪兽的血量与攻击力。

Output
请输出一个非负整数,表示森克救下公主最少消耗的血量。

Examples
inputCopy
1 5 3
21 3
outputCopy
3
inputCopy
2 3 1
3 3
4 5
outputCopy
0
Note
对于第一组样例,第一回合森克可以连吃三份"力量炖水果",获得三倍的攻击加成,此时他的攻击力达到 20 点,本回合将怪兽打到只剩 1 点血量,同时本回合他也受到了来自怪兽的 3 点伤害。第二回合,森克的攻击加成消失,而且也没有"力量炖水果"可以吃了,所以他的攻击力回退到 5,但是由于怪兽仅剩 1 点血量,而且森克先手,所以他本回合可以直接将怪兽打死,不用承受本回合怪兽的伤害。因此,打完这只怪兽,森克承受的总伤害为 3 点,即他至少需要消耗 3 点血量才能救下公主。

思路:
贪心就好了,把攻击力大的怪兽排在前面先干掉,然后计算掉的血就是了,这题在case3莫名的WA了几次,对比同学的没发现漏什么,最后不知怎么的就又AC了,可能是没注意数据范围,下次要注意。

题解:

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=1e5+10;
struct node
{
	long long d,x;//怪兽血量、攻击力  
	bool operator <(const node& a) const
	{
		return x>a.x;
	}
}gu[MAXN];
int main()
{
	int n,k,c;
	long long  xl=0;

	cin>>n>>k>>c;
	for(int i=1;i<=n;i++)
	cin>>gu[i].d>>gu[i].x; 
	sort(gu+1,gu+n+1);

    for(int i=1;i<=n;i++)
    {
        if(k<gu[i].d)
    	{
    	    if(c>=(gu[i].d-k-1)/k+1)
    	    {
    		   c-=(gu[i].d-k-1)/k+1;
		    }
    	   
    	   else 
    	   {
    		  
    		 	xl+=gu[i].x*((gu[i].d-(c+1)*k-1)/k+1);
    		 	c=0; 

		   }	
		} 
    	  
	}
	cout<<xl<<endl; 
	
	
} 

同学题解:

#include<iostream>
#include<algorithm>
using namespace std;
struct node{
	long long d,x;
	
}a[100005];
bool cmp(struct node rr,struct node pr)
{
	return rr.x > pr.x;
}
int main()
{
	int n,k,c;
	cin>>n>>k>>c;
	int tot=1;
	for(int i=1;i<=n;i++)
	{
		int p,pp;
		cin>>p>>pp;
		if(p>k)a[tot].d=p,a[tot].x=pp,++tot;
	}
	sort(a+1,a+1+tot,cmp);
//	for(int i=1;i<=tot;i++)cout<<a[i].d<<' '<<a[i].x<<'\n';
//	cout<<'\n';
	long long ans=0;
	for(int i=1;i<=tot;i++)
	{
		long long res=a[i].d-k;
		long long cnt;
		if(res%k==0)cnt=res/k;
		else cnt=res/k+1;
		c-=cnt;
		if(c<0)
		{
			ans+=abs(c)*a[i].x;
			c=0;
		}
	}
	cout<<ans<<'\n';
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值