Description
给出一串由 N 个整数组成的数列 a1, a2, a3, …, aN,求问数列中哪两个不同元素的和的绝对值最小。
Input
输入共一组数据,共2行
第一行一个数字 N ,表示数列中元素的个数
第二行共 N 个数字,两两之间用空格分开,表示a1, a2, a3, …, aN
输入保证 2 ≤ N ≤ 1 × 103, − 1 × 108 ≤ ai ≤ 1 × 108Output
输出共1行,两个用空格隔开的数字 i 和 j ,表示 ai + aj 的绝对值最小。
若两对元素的之和的绝对值相同,且都比其它对元素之和的绝对值小,则取编号较小元素的编号较小的一对;若编号较小元素相同,则取编号较大元素的编号较小的一位。
例如,数列: − 1, 1, 1, − 1 中,有|a1 + a2| = |a1 + a3| = |a2 + a4| = |a3 + a4| = 0,它们的绝对值相等且最小。但应输出1 2Sample Input
5
5 4 3 2 1Sample Output
4 5
Hint
#include <bits/stdc++.h>
using namespace std;
int sequence[1005], abs_sum[1005][1005];
int main()
{
int n, x = 0, y = 0, min = 10000005;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> sequence[i];
}
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
abs_sum[i][j] = abs(sequence[i] + sequence[j]);
}
}
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (min > abs_sum[i][j])
{
min = abs_sum[i][j];
x = i;
y = j;
}
}
}
cout << x + 1 << " " << y + 1 << endl;
return 0;
}
//直接枚举即可。
//优化思路:利用树形结构可以维护正数、负数两个表,每次分别在异号中O(logn)找最接近的,在同号中O(1)找绝对值最小的。这里不再实现。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int maxn = 1e3 + 10;
int a[maxn];
int n;
int main()
{
while(scanf("%d", &n) != EOF)
{
for(int i = 0; i < n; i ++)
scanf("%d", &a[i]);
int ansi = 0, ansj = 1;
for(int i = 0; i < n; i ++)
for(int j = i + 1; j < n; j ++)
if(abs(a[i] + a[j]) < abs(a[ansi] + a[ansj]))
ansi = i, ansj = j;
printf("%d %d\n", ansi + 1, ansj + 1);
}
return 0;
}