1. 程式人生 > >PAT-ADVANCED1048——Find Coins

PAT-ADVANCED1048——Find Coins

題目描述:

題目翻譯:

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++解題報告: