Vjudge Bound Found

トピックリンクバインドが見つかりました
題名

N個の整数があり、負または正の場合があります。数値tを与え、連続間隔の合計の絶対値がtに最も近くなるように、N個の数値から連続間隔を見つけ、連続間隔の合計と間隔の上限と下限の絶対値の合計を見つけます。

アイデア
  • ルーラーテイクメソッド
    名前が示すように、ルーラーのようなセグメントをテイクします。ルーラーテイクメソッドは通常、サブスクリプトのペアを配列、つまり選択した間隔の左右のエンドポイントに保存し、実際の状況に応じてインターバルの左右のエンドポイントを継続的に進めて答えを取得します。
  • ルーラーメソッドはいつ使用できますか?
    私自身の理解は次のとおりです。答えは連続間隔または連続間隔です(状況を満たすために複数の間隔がある場合があります。質問では最適な間隔を見つける必要があります)。通常、間隔は配列の左端から動的です。右端に移動します。間隔の範囲が拡大する(右の終点が右に移動する)ほど、回答に近づき、間隔が縮小する(左の終点が右に移動する)ほど、回答は遠くなります。また、現在の間隔の状態に応じて、左端点と右端点のどちらが右にシフトしているかを判断できます。





  • 間隔の開始と終了繰り返し進めて、条件を満たす最小間隔を見つける方法をルーラー法と呼びます。
  • この質問で
    は、配列内の数値が正または負であるため、ルーラーメソッドは使用できません。ルーラー方式を使用し、最適な間隔の上限と下限を見つけるために、最初に接頭辞の合計を取得してから、接頭辞の合計に従って並べ替えることができます。並べ替えの際、接頭辞の合計と添え字は、構造の並べ替え用の構造に格納されます。 。間隔とsum <tの場合は、右端点を右に移動します。sum> tの場合は、左端点を右に移動して、合計がtにできるだけ近くなるようにします。間隔が動的に変換されると、回答を更新できます。
コード
//#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;
}

おすすめ

転載: blog.csdn.net/weixin_43311695/article/details/108629099