PAT-ADVANCED1048——Find Coins

本文详细介绍了PAT-ADVANCED 1048题目的两种高效解法:双指针法和二分查找法。通过实例演示了如何在给定的硬币面值中找出两个硬币,其面值之和等于指定金额。代码实现清晰,适合初学者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED

原题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805432256675840

题目描述:

题目翻译:

1048 寻找硬币

伊娃喜欢收集来自宇宙各处的硬币,包括其他一些像火星一样的行星。 有一天,她参观了一个可以接受各种硬币作为付款的通用购物中心。 但是,付款有一个特殊要求:对于每个账单,她只能使用两个硬币来支付确切的金额。 但是她有多达10 ^ 5个硬币,她需要你的帮助。 对于任何给定数额的钱,你应该告诉她,她是否可以找到两个硬币来支付它。

输入格式:

每个输入文件包含一个测试用例。对每个测试用例,第一行包含两个正整数:N(<= 10 ^ 5,代表硬币总数),M(<= 10 ^ 3,代表伊娃需要支付的总金额)。第二行包含了N个不超过500的正数,分别代表N个硬币的面值。一行中的所有数字都由一个空格分隔。

输出格式:

对每个测试用例,在第一行打印选取的两个硬币面值V1和V2,使其满足条件V1 + V2 = M且V1 < V2。如果这样的解决方案不唯一,输出V1最小的解决方案。如果找不到解决方案,输出No Solution。

输入样例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

知识点:双指针、二分查找法

思路一:先对N枚硬币按面值从小到大排序,再用左右双指针遍历即可

由于题目只要找V1最小的一个解决方案,一旦找到解决方案就break出循环。

时间复杂度是O(NlogN)。空间复杂度是O(1)。

C++代码:

#include<iostream>
#include<algorithm>

using namespace std;

int main(){
	int N, M;
	scanf("%d%d", &N, &M);
	int nums[N];
	for(int i = 0; i < N; i++){
		scanf("%d", &nums[i]);
	}
	sort(nums, nums + N);
	int left = 0;
	int right = N - 1;
	while(left < right){
		if(nums[left] + nums[right] == M){
			printf("%d %d\n", nums[left], nums[right]);
			break;
		}else if(nums[left] + nums[right] < M){
			left++;
		}else{
			right--;
		}
	}
	if(left >= right){
		printf("No Solution\n");
	}
	return 0;
}

C++解题报告:

思路二:先对N枚硬币按面值从小到大排序,再用二分查找法

对于每一个索引i,寻找在[i + 1, N)范围内寻找另一个索引j,使得nums[i] + nums[j] == M。一旦找到就break出循环。

时间复杂度是O(NlogN)。空间复杂度是O(N)。

C++代码:

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int main(){
	int N, M;
	scanf("%d %d", &N, &M);
	int nums[N];
	for(int i = 0; i < N; i++){
		scanf("%d", &nums[i]);
	}
	sort(nums, nums + N);
	vector<int> result;
	for(int i = 0; i < N; i++){
		int find = M - nums[i];
		int j = lower_bound(nums + i + 1, nums + N, find) - nums;
		if(j == N){
			continue;
		}
		if(nums[j] + nums[i] == M){
			result.push_back(nums[i]);
			result.push_back(nums[j]);
			break;
		}
	}
	if(result.size() == 0){
		printf("No Solution\n");
	}else{
		printf("%d %d", result[0], result[1]);
	}
	return 0;
} 

C++解题报告:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值