P7870 「Wdoi-4」兔已着陆 题解

第一步:先看题

这道题其实也不能顺着题去想,要不然不是空间炸,就是时间炸,因为数据范围非常大!;题目

P7870 「Wdoi-4」兔已着陆 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

第二步:细观察

这题目看起来和写作文一样,十分繁琐,让人头疼;所提要学会提取有用信息:

1.清兰使用河童的机器可以生产出各种各样颜色的团子。她发现,对于颜色为 𝑐 的团子,它的售价为 𝑐。同时,团子机器有个特性,那就是生产出来的团子的颜色必然是一段连续的整数

2. 1 l r:团子机器生产出来了颜色为 𝑙,𝑙+1,⋯𝑟−1,𝑟l,l+1,⋯r−1,r 的团子。清兰将这些团子依次入栈。也就是在栈顶依次加入 𝑙,𝑙+1,𝑙+2,⋯𝑟−1,𝑟l,l+1,l+2,⋯r−1,r 。2 k:有一位客人想要购买 𝑘k 个团子。此时清兰会依次从栈顶取出 𝑘 个团子并售出。保证 𝑘 不大于当前栈内的团子个数。

3.

  • 对于前 30%的数据,𝑛,𝑙,𝑟≤100n,l,r≤100
  • 对于另外 20% 的数据,𝑙=𝑟
  • 对于另外 20% 的数据,𝑘≤10
  • 对于 100% 的数据,1≤𝑛≤5×10的5次方0≤𝑙≤𝑟≤10的6次方1≤𝑘≤10的12次方

事实上,善于观察和运用这些特殊情况和数据范围,有助于我们在考场上拿更多的分数。

第三步:理思路

如果想要拿到满分,那么这道题就不能把这些“团子”一个一个存进去,因为1≤𝑘≤10的12次方!!!;要把“团子”一批一批地放进去,建立一个栈,么一次存储都要把第一个的价格、最后一个的价格和这一批团子总数存进去;每一次取出,如果k大于最上面一批的数量,k就一直减去最上面一批的数量,把栈弹出一层,直到k比最上面一批的数量小为止,在计算卖不完一批“团子”的价格时,只需(第一个“团子”+第一个“团子”-需要的数量+1)*需要的数量/2就可以了,再把原先的弹掉,重新放进去剩余的;最后输出总价格。

第四步:看代码

#include<bits/stdc++.h>
using namespace std;
struct bz{
	long long h,b,m;
};
long long n,l,r,zl,o,ti=1,ans;
stack<bz>stk;
bz k;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>zl;
		if(zl==1){
			cin>>l>>r;
			stk.push(bz{r,l,r-l+1});
		}else{
			cin>>o;
			ans=0;
			while(o>stk.top().m){
				ans+=(stk.top().b+stk.top().h)*stk.top().m/2;
				o-=stk.top().m;
				stk.pop();
			}
			cout<<((stk.top().h-o+1)+(stk.top().h))*o/2+ans<<endl;
			k=bz{stk.top().h-o,stk.top().b,stk.top().m-o};
			stk.pop();
			if(k.m!=0){
				stk.push(k);
			}
		}
	}
	return 0 ;	
}

这下,问题应该就不大了,如果有更加简单的方法,欢迎评论;

第五步:点个赞再走吧

  • 37
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值