1.首先贡献一波模板
Subsequence通道:
#include<iostream>
#include<stdio.h>
#include<cmath>
using namespace std;
const int maxn = 1e5+5;
int a[maxn],n,s,t,res;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&s);
for(int i = 0;i<n;i++)
{
scanf("%d",&a[i]);
}
int l,r,sum;
sum = 0;l = 0;r = 0;res = n+1;
for(;;)
{
while(r<n&&sum<s)
{
sum+=a[r++];
}
if(sum < s)
break;
res = min(res,r - l);
sum-=a[l++];
// cout<<"sum = "<<sum<<endl;
}
if(res>n)
printf("0\n");
else
printf("%d\n",res);
}
return 0;
}
2.好,接下来就是重点了,题目讲解。
Bound Found
Time Limit: 5000MS | Memory Limit: 65536K | |||
Total Submissions: 6550 | Accepted: 2112 | 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
题目通道:Bound Found
题意寻找不小于给定数的最接近给定数的区间和
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 100100;
const int INF = 1<<30;
int n,k,a[maxn],d,ans;
struct nod
{
int v;
int id;
};
struct nod sum[maxn];
bool cmp(nod a,nod b)
{
if(a.v == b.v)
return a.id>b.id;
return a.v<b.v;
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF&&(n||k))
{
sum[0].v = 0;sum[0].id = 0;
for(int i = 1;i<=n;i++)
{
scanf("%d",&a[i]);
sum[i].v=sum[i-1].v+a[i];//区间内的和
sum[i].id = i;//记录id号
}
for(int i = 0;i<k;i++)
{
ans = INF;
scanf("%d",&d);
int rex = 0,rey = 1,x,y,an;
while(rex<=n&&rey<=n)
{
int sumx = abs(sum[rey].v - sum[rex].v);
int de = abs(d - sumx);
if(de<ans)//记录最小的与其差值
{
ans = de;
x = sum[rex].id;y = sum[rey].id;
an = sumx;
}
if(sumx>d)
rex++;
else if(sumx<d)
rey++;
else
break;
if(rex == rey)rey++;
}
if(x>y)//保证最小的在前面
{
int t = x;
x = y;
y = t;
}
printf("%d %d %d\n",an,x+1,y);//前面的那个Id是区间前的一个数,未记录所以应该x+1
}
}
return 0;
}