1044 Shopping in Mars (25 分)

题意:求一串的数字中连续的一段,使得这个连续的段内数字的和恰好等于所期望的值m。如果不能找到恰好等于,就找让自己付出最少的价格(总和必须大于等于所给值)的那段区间。求所有可能的结果。

分析:简单模拟有两个超时。后来想到因为sum数组是递增的,所以改用二分法查找~子函数的作用是二分查找,修改tempans和j的值~一开始接收输入的时候可以直接保存它的sum函数,即sum[i]表示1~i的所有数字的总和~
 

Sample Input 1:

16 15

3 2 1 5 4 6 8 7 16 10 15 11 9 12 14 13

Sample Output 1:

1-5

4-6

7-8

11-11

Sample Input 2:

5 13

2 4 5 7 9

Sample Output 2:

2-4 4-5 

#include<bits/stdc++.h>
using namespace std;
int sum[100005];
vector<int> tmp,ans;
int n,m;
void BinarySearch(int i,int &j,int &tmpans) {
	int left=i,right=n,mid;  //左闭右开
	while(left<right) {
		mid=(left+right)>>1;
		if(sum[mid]-sum[i-1]>=m) right=mid;
		else left=mid+1;
	}
	j=right;
	tmpans=sum[j]-sum[i-1];  //i到j的部分和
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) {  //部分和
		scanf("%d",&sum[i]);
		sum[i]+=sum[i-1];
	}
	int minans=sum[n];
	for(int i=1; i<=n; i++) {
		int j,tmpans;
		BinarySearch(i,j,tmpans);   //j和tmpans使用引用
		if(tmpans>minans) continue; //直接continue:大于minans
		else if(tmpans>=m) {        //否则如果>=m
			if(tmpans<minans) { //若小于则清空向量,更新minans
				ans.clear();
				minans=tmpans;
                                ans.push_back(i);   
			        ans.push_back(j);
			}
                        else if(tmpans==minans){ //当前最优解的另一种方案
                                ans.push_back(i);   
			        ans.push_back(j);
                        }
		}
	}
	for(int i=0; i<ans.size(); i+=2)
		cout<<ans[i]<<"-"<<ans[i+1]<<endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值