标签:namespace can 表示 出现 absolute sam air contains pre
Input
Output
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
题意:从数列中找出连续序列,使得和的绝对值与目标数之差最小,对于每次查询,输出三个整数sum,l,r,分别表示其绝对值与目标数之差最小的连续序列值与此连续序列的左右端点
如果有多种解,可输出其任意一种。
思路:对于连续区间和,我们要想到前缀和,所以开一个pair(int,int) 分别记录前缀和的值和此时的位置。
然后用 sum[r] - sum[l] 算出区间和。
如果区间和sum[r] - sum[l] > m 比目标值要大,那么尾部就要推进 L++
如果区间和sum[r] - sum[l] < m 比目标值要小,那么头部就要推进 R++
sum[r] - sum[l] = m 的时候break出来就可以了。还有注意要防止出现空区间(代码中已注释)
代码
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <string>
#include <cmath>
#include <vector>
#include <stack>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
//#include <unordered_map>
#define Fbo friend bool operator < (node a, node b)
#define mem(a, b) memset(a, b, sizeof(a))
#define FOR(a, b, c) for (int a = b; a <= c; a++)
#define RFOR(a, b, c) for (int a = b; a >= c; a--)
#define off ios::sync_with_stdio(0)
#define sc(a) scanf("%d",&a)
#define pr(a) printf("%d",a);
bool check1(int a) { return (a & (a - 1)) == 0 ? true : false; }
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f;//1e10
const int mod = 1e9 + 7;
const int Maxn = 1e6+9;
const double pi = acos(-1.0);
const double eps = 1e-8;
int a[Maxn], n, k, m;
pii sum[Maxn];
int main() {
while (~scanf("%d%d", &n, &k)) {
if (n == 0 && k == 0)break;
sum[0] = make_pair(0, 0);
FOR(i, 1, n) {
sc(a[i]);
sum[i] = make_pair(sum[i - 1].first + a[i], i); //用pair将前缀和存起来
}
sort(sum, sum + 1 + n);
while (k--) {
sc(m);
int l = 0, r = 1, ans, dis=INF; //l=0, r=1 防止 l=r的时候出现空区间
int ansl, ansr;
while (r <= n) {
int t = sum[r].first - sum[l].first;//两点之间的区间和
// cout << sum[r].first << "——" << sum[l].first << endl;
// cout << t << endl;
if (abs(t - m) < dis) {
dis = abs(t - m);
ansl = sum[l].second;
ansr = sum[r].second;
ans = t;
// cout << ansl << "————" << ansr << endl;
}
if (t < m) r++;//区间可以变大
else if (t > m) l++;//区间可以变小一点
else break;
if (l == r) r++; // 防止出现空区间
}
if (ansl > ansr) swap(ansl, ansr);
printf("%d %d %d\n", ans, ansl+1, ansr);
}
}
return 0;
}
标签:namespace can 表示 出现 absolute sam air contains pre
原文地址:https://www.cnblogs.com/AlexLINS/p/12690204.html