pat 甲级 1048 Find Coins (25 point(s))散列表和二分查找

题意:第一行,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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值