Vjudge Bound Found

Topic link Bound Found
Title

There are N integer numbers, which can be negative or positive. Give a number t, and then find a continuous interval from the N numbers so that the absolute value of the continuous interval sum is closest to t, and find the absolute value sum of the continuous interval sum and the upper and lower bounds of the interval.

Ideas
  • Ruler taking method
    As the name suggests, take a segment like a ruler. The ruler taking method usually saves a pair of subscripts to the array, that is, the left and right end points of the selected interval, and then continuously advances the left and right end points of the interval according to the actual situation to get the answer.
  • When can I use the ruler method?
    My own understanding is: the answer is in a continuous interval or a continuous interval (there may be multiple intervals to satisfy the situation, the question requires you to find an optimal interval), generally the interval is dynamic from the left end of the array Move to the right end. As the range of the interval expands (the right end point moves to the right), the closer it is to the answer, and the interval shrinks (the left end point moves to the right), the farther away the answer is. And it can judge whether the left end point or the right end point is shifted to the right according to the state of the current interval.
  • Example The method of




    repeatedly advancing the beginning and end of the interval to find the minimum interval that satisfies the condition is called the ruler method.
  • For this question,
    because the numbers in the array are positive or negative, the ruler method cannot be used. In order to be able to use the ruler method, and to find the upper and lower bounds of the optimal interval, the prefix sum can be obtained first, and then sorted according to the prefix sum. When sorting, the prefix sum and subscript are stored in a structure for structure sorting . If the interval and sum<t, move the right end point to the right: If sum>t, move the left end point to the right, so as to ensure that the sum is as close to t as possible, and the answer can be updated when the interval is dynamically transformed
Code
//#pragma GCC optimize(2)
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;

typedef long long ll;
typedef unsigned long ul;
typedef unsigned long long ull;
#define pi acos(-1.0)
#define e exp(1.0)
#define pb push_back
#define mk make_pair
#define fir first
#define sec second                     
#define scf scanf
#define prf printf

typedef pair<int,int> pa;
const int INF=0x3f3f3f3f;
const int MAX_N=1e5+7;
int N,K,T;
int num[MAX_N];
struct node{
    
    
	int s,pos;
	bool operator<(const node &a)const{
    
    //从小到大排序 
		if(s!=a.s)
		return s<a.s;
		return pos<a.pos;
	}
};
vector<node>V;
void do_(int t){
    
    
	int L=0,R=1,aL,aR,minn=INF,sum=0,ans;
	while(L<=R&&R<V.size()){
    
    
		int sum=V[R].s-V[L].s;
		if(abs(sum-t)<minn){
    
    
			minn=abs(sum-t);
			ans=sum;
			aR=max(V[R].pos,V[L].pos);
			aL=min(V[R].pos,V[L].pos);
		}
		if(sum<t)
		R++;
		else if(sum>t)
		L++;
		else
		break;
		if(L==R){
    
    
			R++;
		}
	}
	prf("%d %d %d\n",ans,aL+1,aR);
}
int main()
{
    
    
//  freopen(".../.txt","w",stdout);
//  freopen(".../.txt","r",stdin);
//	ios::sync_with_stdio(false);
	int i,j,k;
	while(~scf("%d %d",&N,&K)&&(N||K)){
    
    
		V.clear();
		for(i=1;i<=N;i++){
    
    
			scf("%d",&num[i]);
		}
		int tmp=0;
		V.pb({
    
    0,0});
		for(i=1;i<=N;i++){
    
    
			tmp=tmp+num[i];
			V.pb({
    
    tmp,i});
		}
		sort(V.begin(),V.end());
		for(i=0;i<K;i++){
    
    
			scf("%d",&T);
			do_(T);
		}
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43311695/article/details/108629099