描述
题解
这道题两种办法解,两种办法的通性是都需要排序,但是数据结构截然不同。
第一种办法是源数据进行从小到大排序,然后定一个哨兵flag
,来卡住查找的范围,以此来达到减少查找次数。
第二种办法比较巧,将复杂度为O(n*m)降低为O(n)。效率略微提高,使用的手段是将数据结构改造了一下,给源数据捆绑了一个antival
的辅助数据。当a[i].val < k / 2
时,a[i].antival = a[i].val
反之等于k - a[i].val
,然后根据antival
作为主键进行排序,查找时,直接查找相邻的两项antival
相等的结果,这里需要说明的是,因为题意上说每个数据都互不相同,所以相等的两个antival
对应的val
一定是相加等于K。
代码
One:
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAXN = 5e4 + 5;
int A[MAXN];
int main(int argc, const char * argv[])
{
freopen("input.txt", "r", stdin);
int K, N;
while (cin >> K >> N)
{
bool tag = false;
for (int i = 0; i < N; i++)
{
scanf("%d", A + i);
}
sort(A, A + N);
int B;
int flag = N;
for (int i = 0; i < N - 1; i++)
{
B = K - A[i];
for (int j = flag - 1; j > i; j--)
{
if (B == A[j])
{
printf("%d %d\n", A[i], B);
flag = j;
tag = true;
break;
}
else if (B > A[j])
{
flag = j + 1;
break;
}
}
}
if (!tag)
{
puts("No Solution");
}
}
return 0;
}
Two:
#include <cstdio>
#include <algorithm>
using namespace std;
#define maxn 50010
struct node
{
int val, antival;
} a[maxn];
int cmp(node x, node y)
{
if (x.antival == y.antival)
{
return x.val < y.val;
}
return x.antival < y.antival;
}
int main()
{
int n, i, k;
while (scanf("%d%d", &k, &n) != EOF)
{
for (i = 0; i < n; ++i)
{
scanf("%d", &a[i].val);
if (a[i].val < k/2)
{
a[i].antival = a[i].val;
}
else
{
a[i].antival = k - a[i].val;
}
}
sort(a, a + n, cmp);
bool sign = false;
for (i = 0; i < n - 1; ++i)
{
if (a[i].antival == a[i + 1].antival)
{
printf("%d %d\n", a[i].val, a[i + 1].val);
sign = true;
}
}
if (!sign)
{
printf("No Solution\n");
}
}
return 0;
}