题意:第一行,n个硬币,要付pay这么多钱
第二行,n个硬币的种类;
取两个数和要为pay的硬币种类;(如果有不同的选择,选第一个是最小的那个,比如pay为15)
有两个方案,2 13和4 11,取2和13;
思路:用hashtable记录硬币的个数,只有两种情况,①是pay=a[i]*2(两个硬币相同,恰好凑成pay),②pay=a[i]+(pay-a[i]),两个硬币不相同,两个硬币的和为pay,如果是情况①,就要满足该硬币数>1(起码要有两个),如果是情况②,就要满足,两种硬币的个数!=0。
注意点,如果输出硬币种类相同就要对应hashtable>1(起码有两个),如果是测试点1过不去就是因为没有设置硬币的份额要小于pay的前提,如下;
一、散列表代码:
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
const int maxn=100010;
int a[maxn]={0};
int hashtable[maxn]={0};
int n,pay;
cin>>n>>pay;
for(int i=0;i<n;i++){
cin>>a[i];
hashtable[a[i]]++;
}
sort(a,a+n);
for(int i=0;i<n;i++){
if(a[i]!=pay-a[i]&&hashtable[a[i]]!=0&&hashtable[pay-a[i]]!=0){
cout<<a[i]<<" "<<pay-a[i];
return 0;
}else if(a[i]==pay-a[i]&&hashtable[a[i]]>1){
cout<<a[i]<<" "<<a[i];
return 0;
}
}
cout<<"No Solution";
return 0;
}
二、二分查找代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100010;//要开到这个程度,不然会发生段错误;
int a[maxn]={0};
int binarysearch(int l,int r,int x){//模板3,在a[]中判断该值pay-a[i]存不存在;
while(l<=r){
int mid=l+(r-l)/2;
if(a[mid]>x){
r=mid-1;
}else if(a[mid]<x){
l=mid+1;
}else {
return mid;
}
}
return -1;
}
int main(){
int n,pay;
cin>>n>>pay;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
for(int i=0;i<n;i++){
int l=i;
int r=binarysearch(l,n,pay-a[i]);
if(r!=-1&&l!=r){//如果数列里面没有两个硬币和=pay,单单有一个硬币的价值就等于pay是不行的,必须要两种硬币,除非是两个相同的,比方说pay=15,如果a[i]=15=pay不行;
cout<<a[l]<<" "<<a[r];
return 0;
}
}
cout<<"No Solution";
return 0;
}