伊娃喜欢从整个宇宙中收集硬币。
有一天,她去了一家宇宙购物中心购物,结账时可以使用各种硬币付款。
但是,有一个特殊的付款要求:每张帐单,她只能使用恰好两个硬币来准确的支付消费金额。
给定她拥有的所有硬币的面额,请你帮她确定对于给定的金额,她是否可以找到两个硬币来支付。
输入格式
第一行包含两个整数 N 和 M,分别表示硬币数量以及需要支付的金额。
第二行包含 N 个整数,表示每个硬币的面额。
输出格式
输出一行,包含两个整数 V1,V2,表示所选的两个硬币的面额,使得 V1≤V2 并且 V1+V2=M。
如果答案不唯一,则输出 V1 最小的解。
如果无解,则输出 No Solution。
数据范围
1≤N≤105,
1≤M≤1000
输入样例1:
8 15
1 2 8 7 2 4 11 15
输出样例1:
4 11
输入样例2:
7 14
1 8 7 2 4 11 15
输出样例2:
No Solution
答案:
解法一:哈希表(边存边找)
思路:边读数据,边记录即可。若有两个硬币,更新最小值。
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
const int N = 1e5 + 10;
const int M = 555;
using namespace std;
map<int,int> Hash;
int main()
{
int n,m;
cin>>n>>m;
int k;
int minn=INF;
for(int i=0;i<n;i++){
cin>>k;
if(Hash.count(m-k)){
minn=min(minn,min(k,m-k));
}
Hash[k]++;
}
if(minn==INF) cout<<"No Solution"<<endl;
else cout<<minn<<" "<<m-minn<<endl;
return 0;
}
解法二:哈希表(存完再找)
思路:使用hash表存储所有的硬币面额,O(N)时间扫描一遍hash表,每次寻找hash[i]
和hash[k-i]
(k为消费金额)是否存在即可.
#include <iostream>
#include<bits/stdc++.h>
#include<unordered_map>
#define ll long long
#define INF 0x3f3f3f3f
const int N = 1e5 + 10;
const int M = 555;
using namespace std;
unordered_map<int,int> Hash;
int main(){
int n,m;
cin>>n>>m;
int k;
int a[2]={1010,1010};
for(int i=0;i<n;i++){
cin>>k;
Hash[k]++;
}
for(auto &i:Hash){
i.second--;
if(Hash.count(m-i.first) && Hash[m-i.first]){
if(min(m-i.first,i.first)<min(a[0],a[1])){
a[0]=min(m-i.first,i.first);
a[1]=max(m-i.first,i.first);
}
}
}
if(a[1]!=1010 && a[0]!=1010) cout<<a[0]<<' '<<a[1]<<endl;
else cout<<"No Solution"<<endl;
return 0;
}
解法三:双指针
第一次用的两个for循环剪枝T了,换用了双指针才过
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
const int N = 1e5 + 10;
const int M = 555;
using namespace std;
int a[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+1+n);
bool flag=0;
int maxn;
int minn;
for(int i=1,j=n;i<=n;i++){
while(i<j&&a[i]+a[j]>m) j--;
if(i<j&&a[i]+a[j]==m){
minn=a[i];
maxn=a[j];
flag=1;
break;
}
}
if(!flag) cout<<"No Solution"<<endl;
else cout<<minn<<" "<<maxn<<endl;
return 0;
}