PAT A1044 Shopping in Mars(二分法)

Shopping in Mars

1.思路
1)因为是求数列i到j的和,所以用一个sum[i]数列表示前i
个数相加,这样当求i到j的和,只用用sum[j]-sum[i-1]。注意这里是sum[i-1],因为sum[i-1]被减掉了,不算在和里。
2)因为当存在给定的和时,要给出i,j,如果不存在,则要给出最小的大于给定的和的i,j。所以先找出第一个大于给定数的j,然后看看sum[j-1]-sum[i-1]与给定数是否相等,否则就代表找到的sum[j]减去sum[i-1]大于给定数。

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100010;
int nearS = 1000000010;
int sum[maxn], m;
int upper_bound(int L, int R, int x)
{
	int left = L, right = R;
	while(left < right)
	{
		int mid = (left + right)/2;
		if(sum[mid] > x)
		right = mid;
		else 
		left = mid+1;
	}
	return left;
}
int main()
{
	int n;
	scanf("%d%d", &n, &m);
	sum[0] = 0;
	for(int i = 1; i <= n; i++)
	{
		scanf("%d", &sum[i]);
		sum[i] += sum[i-1];
	}
	
	for(int i = 1; i <= n; i++)
	{
		int j = upper_bound(i, n+1, sum[i-1]+m);//这里R为n+1是因为数列中可能没有大于m的数,这样下标自然为n+1
		if(sum[j-1]-sum[i-1] == m)
		{
			nearS = m;
			break;
		}
		else if(j <= n && sum[j]-sum[i-1] < nearS)
		{
			nearS = sum[j]-sum[i-1];//找出最小值
		}
	}
	
	for(int i = 1; i <= n; i++)
	{
		int j = upper_bound(i, n+1, sum[i-1]+nearS);
		if(sum[j-1]-sum[i-1] == nearS)
		printf("%d-%d\n", i, j-1);
	}
}

2.二分法
这里用到了二分法。通常找第一个满足条件的二分法模板为:
例如:找到第一个大于给定数的数组下标。

int binarySearch(int L, int R, int x)
{
	int left = L, right = R;
	while(left < right)
	{
	int mid = (left + right)/2;
	if(sum[mid] > x)//满足某个条件的时候
	right = mid;//这里是因为mid上的那个数也有可能大于x
	else
	left = mid+1;
	}
	return left;
}

还有在给定数列中查找某个数:

int binarySearch(int L, int R, int x)
{
	int left = L, right = R;
	while(left <= right)
	{
	int mid = (left + right)/2;
	if(sum[mid] == x)
	return mid;
	else if(sum[mid] > x)
	right = mid-1;
	else
	left = mid+1;
	}
	return -1;//找不到
}

这里用left <= right是因为当找不到这个数的时候,left就已经大于right了。而上面用left<right是因为要找到第一个大于给定数的下标就已经假设这个数存在,也就是left=right的时候了。

上面都是在【left,right】闭区间内找,当区间为左开右闭的时候(left,right】则不一样。

int binarySearch(int L, int R, int x)
{
	int left = L, right = R;
	while(left+1 < right)
	{
	int mid = (left + right)/2;
	if(sum[mid] > x)
	right = mid;
	else
	left = mid;
	}
	return right;
}
发布了17 篇原创文章 · 获赞 0 · 访问量 117

猜你喜欢

转载自blog.csdn.net/weixin_45486992/article/details/104867576
今日推荐