8.2暑期第八节课下午总结

最后更新于 2025-08-02 21:46:35
作者
分类 个人记录

P3984 高兴的津津

错误原因

在判断津津高兴时的天数中再次获得奖牌时的情况的条件写错了

解题思路

1、应该判断几次

至于为什么要把它单独拎出来讲,因为这题的条件不允许循环的终点是i<=n,在判断时,我们要把a[i+1]和a[i]的差进行判断,可是当我们判断到a[n]时,a[i+1]会因为没有输入而默认为0,这样就会导致a[i+1]-a[i]为负数,造成程序错误

2、如何判断

当a[i+1]-a[i]>=t时,证明津津在获得一块奖牌后可以高兴的t天内没有获得奖牌,所以高兴的天数直接加t

否则就代表津津在获得一块奖牌后可以高兴的t天内获得了奖牌,就会打断之前一块奖牌所会高兴的t天而开始新的高兴的t天

同时,因为津津必会获得一块奖牌,所以累加器sum初始值应为t

最终代码

#include<bits/stdc++.h>
using namespace std;
long long a[2000005];
int main(){
	long long n,t,x;
	cin>>n>>t;
    long long sum=t;
	for(int i=1;i<=n;i++){
		cin>>a[i];
        
	}
	for(int i=1;i<n;i++){
        if(a[i+1]-a[i]>=t){
            sum+=t;
            
        }else{
            sum+=a[i+1]-a[i];
            
        }
    }
	cout<<sum;
	return 0;
}

B4006 [GESP202406 四级] 宝箱

错误原因

未使用前缀和

解题思路

1、先排序,后用前缀和

这题说小杨的背包在最大价值的宝箱与最小价值的宝箱的差超过k就会废掉,所以前缀和才是最优解

不过在此之前,我们得先排序,使前缀和的数也有序

代码:

int a[1005],sum[1005];
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1);
for(int i=1;i<=n;i++){
	sum[i]=sum[i-1]+a[i];
}

2、取最大值

由于我们已经把前缀和求出来了,所以只需要一个双重for循环和一个ans比较大小即可解决

当a[j]-a[i]<=k时,证明背包不会坏,则定义一个res=sum[j]-sum[i-1]表示能装的金子数,然后把ans与res进行比较,让ans等于较大的那一个,最后等循坏结束,输出ans

代码:

int ans=0;
for(int i=1;i<=n;i++){
	for(int j=i;j<=n;j++){
		if(a[j]-a[i]<=k){
			int res=sum[j]-sum[i-1];
			ans=max(ans,res);
		}
	}
}
cout<<ans;

最终代码

#include<bits/stdc++.h>
using namespace std;
int a[1005],sum[1005];
int main(){
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>a[i];
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		sum[i]=sum[i-1]+a[i];
	}
	int ans=0;
	for(int i=1;i<=n;i++){
		for(int j=i;j<=n;j++){
			if(a[j]-a[i]<=k){
				int res=sum[j]-sum[i-1];
				ans=max(ans,res);
			}
		}
	}
	cout<<ans;
	return 0;
}