法一:二分
碎碎念:自己用vetor<int>
存每一个硬币,如果直接暴力枚举,N=1e5
,时间复杂度为N^2=1e10
,TLE,可以用二分
查找需要的硬币,二分复杂度O(logN)
,总1e5×5log=2e6
可以过。
半个小时写出来的,但是有个测试点没过,自己没有考虑到每个硬币只能用一次,当最后r==i(i为起始位置)
,就无解。其中二分找的每一次都是最靠近右边的,因为从小到大枚举,要保证找的位置不能与起始位置相同。
下面是两个出错的测试样例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int N = 100010;
vector<int> coins;
vector<pair<int, int>> res;
int n, m;
//二分找靠近右边的,因为左边的不能多选
bool check(int i, int &j) //在coins中找到j,与coins[i]相加等于m,
{
int l = i, r = coins.size()-1;
while (l < r)
{
int mid = l + r +1 >> 1;
if (coins[mid]+coins[i] <= m) l = mid;
else r = mid-1;
}
if (r == i) return false;
if (coins[i] + coins[r] == m)
{
j = r;
return true;
}
return false;
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
int x;
cin >> x;
coins.push_back(x);
}
sort(coins.begin(), coins.end());
for (int i = 0; i < coins.size(); i++)
{
int j;
if (check(i, j))
{
res.push_back({coins[i], coins[j]});
}
}
if (res.empty()) puts("No Solution");
else
{
sort(res.begin(), res.end());
cout << res[0].first << ' ' << res[0].second << endl;
}
return 0;
}
法二:双指针
先排序l= 0, r = length-1
, a[l]+a[r]>m,r左移,小了,l右移
复杂度为sort
O(n logn), 双指针复杂度 O(N)
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int a[N];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a+n);
int x = -1, y = -1; //最后的答案
int l = 0, r = n-1; //左右指针
while (l < r)
{
if (a[l] + a[r] == m)
{
x = a[l], y = a[r];
break;
}
else if (a[l] + a[r] < m)
l++;
else r--;
}
if (~x) cout << x << ' ' << y << endl;
else puts("No Solution");
return 0;
}
法三:unordered_set
O(N)
枚举每一个数,如果他对应的结果不在表中,就把这个数加到表中,如果在,就让小的为第一个解,同时更新最小的解。
#include <iostream>
#include <unordered_set>
#include <algorithm>
using namespace std;
unordered_set<int> set;
int main()
{
int n, m;
cin >> n >> m;
int x = 1e9, y; //最后的答案
for (int i = 0; i < n; i++)
{
int a;
cin >> a;
int b = m-a; //配对的数
if (!set.count(b)) //找不到,就插到集合中
set.insert(a);
else //若存在
{
set.insert(a);
if (a > b) swap(a, b); //第一个硬币值最小
if (a < x) x = a, y = b; //若第一个解更小,则更新
}
}
if (x == 1e9) puts("No Solution");
else cout << x << ' ' << y << endl;
return 0;
}