寒假第三周训练——尺取题目汇总

Bound Found
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions:5254 Accepted:1686 Special Judge

Description

Signals of most probably extra-terrestrial origin have been received and digitalized by The Aeronautic and Space Administration (that must be going through a defiant phase: "But I want to use feet, not meters!"). Each signal seems to come in two parts: a sequence of n integer values and a non-negative integer t. We'll not go into details, but researchers found out that a signal encodes two integer values. These can be found as the lower and upper bound of a subrange of the sequence whose absolute value of its sum is closest to t. 

You are given the sequence of n integers and the non-negative target t. You are to find a non-empty range of the sequence (i.e. a continuous subsequence) and output its lower index l and its upper index u. The absolute value of the sum of the values of the sequence from the l-th to the u-th element (inclusive) must be at least as close to t as the absolute value of the sum of any other non-empty range.

Input

The input file contains several test cases. Each test case starts with two numbers n and k. Input is terminated by n=k=0. Otherwise, 1<=n<=100000 and there follow n integers with absolute values <=10000 which constitute the sequence. Then follow k queries for this sequence. Each query is a target t with 0<=t<=1000000000.

Output

For each query output 3 numbers on a line: some closest absolute sum and the lower and upper indices of some range where this absolute sum is achieved. Possible indices start with 1 and go up to n.

Sample Input

5 1
-10 -5 0 5 10
3
10 2
-9 8 -7 6 -5 4 -3 2 -1 0
5 11
15 2
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
15 100
0 0

Sample Output

5 4 4
5 2 8
9 1 1
15 1 15
15 1 15

Source

题意:n个数中取连续的k个数和的绝对值和t相差最小。求出前缀和(从最开始的数加到这个数的和),作差进行尺取,不断更新l和r。

#include <iostream>
#include <cstdio>
#include <algorithm> 
#include <cmath>
using namespace std;
int n,k,t,la,ra,ans;

struct node 
{
	int id,sum;
}a[100005];

bool cmp(node a1,node a2)
{
	return a1.sum<a2.sum;
}

int main()
{
	while(cin >> n >> k && n && k)
	{
		int x;
		a[0].sum=0; a[0].id=0;
		for (int i=1;i<=n;i++)
		{
			scanf("%d",&x);
			a[i].id=i;
			a[i].sum=a[i-1].sum+x;
		}
		sort(a,a+n+1,cmp);
		while(k--)
		{
			scanf("%d",&t);
			int l=0,r=1;
			int res=0x3f3f3f3f;
			while(r<=n)
			{
				int y=a[r].sum-a[l].sum;
				if (abs(y-t)<res)
				{
					la=min(a[l].id,a[r].id);
					ra=max(a[l].id,a[r].id);
					ans=y;				
				}
				if (y<t)
					r++;
				else if (y>t)
					l++;
				else
					break;
				if (l==r)
					r++; 
			}
			printf("%d %d %d\n",ans,la,ra);
		}
	}
	return 0;
}
Subsequence
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions:18381 Accepted: 7864

Description

A sequence of N positive integers (10 < N < 100 000), each of them less than or equal 10000, and a positive integer S (S < 100 000 000) are given. Write a program to find the minimal length of the subsequence of consecutive elements of the sequence, the sum of which is greater than or equal to S.

Input

The first line is the number of test cases. For each test case the program has to read the numbers N and S, separated by an interval, from the first line. The numbers of the sequence are given in the second line of the test case, separated by intervals. The input will finish with the end of file.

Output

For each the case the program has to print the result on separate line of the output file.if no answer, print 0.

Sample Input

2
10 15
5 1 3 5 10 7 4 9 2 8
5 11
1 2 3 4 5

Sample Output

2
3

Source

题意:找到连续子串大于s的最小长度,用尺取。

#include <cstdio>
#include <iostream>
using namespace std;
int a[100005];

int main()
{
	int t; cin >> t;
	while (t--)
	{
		int n,s,l=0,r=0,sum=0,ans=0;
		cin >> n >> s;
		for (int i=0;i<n;i++)
			scanf("%d",&a[i]);
		while(l<n)
		{
			while(r<n&&sum<s)
			{
				sum+=a[r];
				r++;
			}
			if (sum<s)
				break;
			if (ans==0||r-l<ans) ans=r-l;
			sum-=a[l];
			l++;
		}
		cout << ans << endl;
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值