Problem Description:
Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for each bill, she could only use exactly two coins to pay the exact amount. Since she has as many as 1 0 5 10^5 105 coins with her, she definitely needs your help. You are supposed to tell her, for any given amount of money, whether or not she can find two coins to pay for it.
Input Specification:
Each input file contains one test case. For each case, the first line contains 2 positive numbers: N N N ( ≤ 1 0 5 \leq 10^5 ≤105, the total number of coins) and M M M ( ≤ 1 0 3 \leq 10^3 ≤103, the amount of money Eva has to pay). The second line contains N N N face values of the coins, which are all positive numbers no more than 500. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in one line the two face values
V
1
V_1
V1 and
V
2
V_2
V2 (separated by a space) such that
V
1
+
V
2
=
M
V_1 + V_2 = M
V1+V2=M and
V
1
≤
V
2
V_1\leq V_2
V1≤V2. If such a solution is not unique, output the one with the smallest
V
1
V_1
V1. If there is no solution, output No Solution
instead.
Sample Input 1:
8 15
1 2 8 7 2 4 11 15
Sample Output 1:
4 11
Sample Input 2:
7 14
1 8 7 2 4 11 15
Sample Output 2:
No Solution
Problem Analysis:
将所有出现的硬币面值及硬币出现次数用哈希表维护,key
为面值,value
为该面值的硬币个数。由于题目要求尽量输出面值最小的两枚硬币
V
1
V_1
V1 和
V
2
V_2
V2,故我们先将数组从小到大排序,然后依次枚举每个面值为
V
i
V_i
Vi 的硬币,并借助建好的哈希表查询对应面值
M
−
V
i
M- V_i
M−Vi 的硬币是否在表中出现过,如果出现过,则输出这两枚硬币的面值。否则继续枚举下一个。
当 V i = M − V i V_i = M - V_i Vi=M−Vi 时,需要特判一下这个面值的硬币是否至少存在两个,否则不能构成一组合法方案。
Code
#include <cstdio>
#include <cstring>
#include <iostream>
#include <unordered_map>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int v[N];
unordered_map<int, int> map;
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ )
{
scanf("%d", &v[i]);
map[v[i]] ++ ;
}
sort(v, v + n);
bool flag = false;
for (int i = 0; i < n; i ++ )
{
if (map[v[i]] != 0 && map[m - v[i]] != 0)
{
if ((v[i] != m - v[i]) || map[v[i]] >= 2)
{
printf("%d %d\n", v[i], m - v[i]);
flag = true;
break;
}
}
}
if (!flag) puts("No Solution");
return 0;
}