首页 > 试题广场 >

Find Coins (25)

[编程题]Find Coins (25)
  • 热度指数:2975 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
Eva loves to collect coins from all over the universe, including some other planets like Mars. One day she visited a universal shopping mall which could accept all kinds of coins as payments. However, there was a special requirement of the payment: for each bill, she could only use exactly two coins to pay the exact amount. Since she has as many as 105 coins with her, she definitely needs your help. You are supposed to tell her, for any given amount of money, whether or not she can find two coins to pay for it.

输入描述:
Each input file contains one test case.  For each case, the first line contains 2 positive numbers: N (<=105, the total number of coins) and M(<=103, the amount of money Eva has to pay).  The second line contains N face values of the coins, which are all positive numbers no more than 500.  All the numbers in a line are separated by a space.


输出描述:
For each test case, print in one line the two face values V1 and V2 (separated by a space) such that V1 + V2 = M and V1 <= V2.  If such a solution is not unique, output the one with the smallest V1.  If there is no solution, output "No Solution" instead.
示例1

输入

8 15
1 2 8 7 2 4 11 15

输出

4 11
拿一个flag记录面值对应的硬币存不存在,有几个
#include<iostream>
#include<vector>
using namespace std;

const int MAX_BUFFER = 510;
int flag[MAX_BUFFER] = {0};
int money,coinNum;

int main(){
	scanf("%d%d",&coinNum,&money);
	for(int i = 0;i < coinNum;i++){
		int coin;
		scanf("%d",&coin);
		flag[coin]++;
	}
	bool success = false;
	int V1,V2;
	for(int i = 1;i <= 500;i++){
		if(!flag[i])	continue;
		int j = money - i;
		if( j < 0 ){
			break;
		}
		if(j > 500){
			continue;
		}
		if(flag[j]){
			if(i == j){
				if(flag[j] >= 2){
					success = true;
					V1 = i<j ? i : j;
					V2 = i>j ? i : j;
					break;
				}
			}else{
				success = true;
				V1 = i<j ? i : j;
				V2 = i>j ? i : j;
				break;
			}
		}
		
	}
	
	if(success){
		printf("%d %d",V1,V2);
	}else{
		printf("No Solution");
	}
	
	return 0;
}

发表于 2017-01-24 21:37:35 回复(0)
更多回答
#include <iostream>
using namespace std;

int main(){
    int hash[1010]={0}; 
    int x,y,a,i;
    cin>>x>>y;
    for(i=0;i<x;i++){                              //计算每个价值的硬币有多少个
        cin>>a;
        hash[a]++;
    }
    for(i=1;i<y;i++){                           //从小到大,保证前一个硬币不大于后一个匹配的硬币
        if(hash[i]&& hash[y-i]){
            if(i!=y-i) break;
            else if(i==y-i && hash[i]>=2) break;   //需要不少于两个一样的价值y/2的硬币
        }
    }
    if(i==y) cout<<"No Solution";
    else cout<<i<<" "<<y-i;

    return 0;
}

编辑于 2018-01-26 01:07:23 回复(1)
import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        int m=sc.nextInt();
        int n=sc.nextInt();
        int[] array=new int[m];
        for(int i=0;i<m;i++){
            array[i]=sc.nextInt();
        }
        Arrays.sort(array);
        int start=0,end=m-1;
        while(start<end){
            if(array[start]+array[end]==n){
                break;
            }else if(array[start]+array[end]<n){
                start++;
            }else{
                end--;
            }
        }
        if(start<end){
            System.out.println(array[start]+" "+array[end]);
        }else{
            System.out.println("No Solution");
        }
    }
}

发表于 2018-10-05 01:03:07 回复(0)
#include<iostream>
#include<algorithm>
using namespace std;

#define MAX 100009

int N, M, V[MAX];
int v1, v2;

int main()
{
	cin >> N >> M; bool has_res = false;
	for (int i = 1; i <= N; ++i)cin >> V[i];

	sort(V + 1, V + N + 1);
	int i = 1, j = N;
	while (i < j) {
		while (i<j && V[i] + V[j] > M)
			--j;
		if (V[i] + V[j] == M) {
			has_res = true; break;
		}
		++i;
	}
	v1 = V[i]; v2 = V[j];

	if (has_res)cout << v1 << " " << v2;
	else cout << "No Solution";

	return 0;
}

发表于 2021-03-16 03:07:55 回复(0)
//二分查找
#include <iostream>
#include <algorithm>
#include <string>
#include <set>
#include <vector>
#include <map>
using namespace std;

//1048 Find Coins
//n<=10^5,m<=10^3,硬币面值<=500

vector<int> c;
int main(){
    int n,m,v;
    cin>>n>>m;
    
    for(int i=0;i<n;++i){
        cin>>v;
        c.push_back(v);
    }
    
    //O(nlogn)
    sort(c.begin(),c.end());
    
    int l = c.size();
    int i,lo,hi,mid;
    bool flag=false;
    //二分查找,O(nlogn)
    for(i =0;i<l;++i){
        //从前往后,[lo,hi)左闭右开
        lo=i+1;
        hi=l;
        while(lo<hi){
            mid = (lo+hi)/2;
            if(c[i]+c[mid]==m){
                flag=true;
                break;
            }
            else if(c[i]+c[mid]>m){
                //偏大,向左找,因为左闭右开,取mid
                hi=mid;
            }
            else{
                lo=mid+1;
            }
        }
        if(flag) break;
    }
    
    if(flag) cout<<c[i]<<" "<<c[mid];
    else cout<<"No Solution";
    return 0;
}


编辑于 2019-08-13 09:32:47 回复(0)
思路:采用头尾指针逐渐向中间逼近查找
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX_MOUNT 100010
int main() {
    int n, m, v1, v2;
    int coin[MAX_MOUNT];
    cin >> n >> m;
    for (int i= 0; i < n; i++) {
        cin >> coin[i];
    }
    sort(coin, coin + n);
    int low = 0, high = n - 1;
    bool isfind = false;
    while (low <= high) {
        int x = m - coin[low];
        while (x < coin[high] && low <= high)
            high--;
        if (coin[low] + coin[high] == m) {
            isfind = true;
            break;
        }    
        low++;
    }
    if(!isfind)
        cout << "No Solution" << endl;
    if(isfind)
        cout << coin[low] << ' ' << coin[high]<< endl;
    return 0;
}

发表于 2019-07-18 09:50:08 回复(0)
n,m = map(int,input().split())
lst = sorted(map(int,input().split()))
start,end = 0,len(lst)-1
while start<end:
    if lst[start]+lst[end]<m:
        start+=1
    elif lst[start]+lst[end]>m:
        end-=1
    else:
        print(str(lst[start])+" "+str(lst[end]))
        break
if start>=end:
    print("No Solution")

发表于 2018-12-02 20:43:43 回复(0)
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{     int N,M,x,hash[1003]={0};     cin>>N>>M;     for(int i=0;i<N;i++)      {         cin>>x;         hash[x]++;     }     int i;     for(i=1;i<M;i++)     {         if(hash[i] && hash[M-i])         {             if(i!=M-1)                 break;             else if(i==M-i && hash[i]>=2)                 break;         }     }     if(i==M)         cout<<"No Solution"<<endl;     else         cout<<i<<" "<<M-i<<endl;     return 0;
}

发表于 2018-03-16 01:21:01 回复(0)
思路就哈希的思路。但PAT有一个错误,哪位能告知下。。。

#include<stdio.h>

bool coins[10005];
int n,m;

int main(){
    scanf("%d %d",&n,&m);
    int tmp;
    for(int i=0;i<n;i++){
        scanf("%d",&tmp);
        coins[tmp]=true;
    }
    bool flag=false;
    for(int i=1;i<(m+4)/2;i++){
        if(coins[i]&&coins[m-i]){
            flag=true;
            printf("%d %d",i,m-i);
            break;
        }
    }
    if(!flag)
        printf("No Solution\n");
    return 0;
}
发表于 2018-03-08 11:33:22 回复(2)
一开始还以为是什么复杂的背包问题, 然后思考了一下,这道题只需要确定两个硬币,直接枚举的话就ok了
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100000 + 10;
const int maxm = 1000 + 10;
int w[maxn], cnt[maxn] = {0};

int main(){
	int n, m;
	bool flag = false;
	scanf("%d %d", &n, &m);
	for(int i=1; i<=n; i++){
		scanf("%d", &w[i]);
		cnt[w[i]] += 1;
	}
	sort(w+1, w+n+1);
	for(int i=1; i<=n; i++){
		int first = w[i];
		int second = m - first;
		cnt[first] --;
		if(cnt[second] && first <= second){
			flag = true;
			printf("%d %d\n", first, second);
			break;
		}
		else
			cnt[first] ++;
	}
	if(!flag) printf("No Solution\n");
	return 0;
}

发表于 2017-08-29 16:16:15 回复(0)
哪位大大能接受下为什么我会输出错误答案312 502,我已经知道答案为什么错误了
,问题是怎么会得到这个答案数组下标最大500,502不是越界了吗,怎么不崩溃


#include<bits/stdc++.h>
using namespace std;
int main(){
    int N,M;
    cin>>N>>M;
     
    vector<int> coinNums(501,0);
    for(int i=0;i<N;i++){
        int c;
        cin>>c;
        coinNums[c]++;
    }
     
    for(int i=1;i<=M/2;i++){
        if(coinNums[i]!=0){
            int other=M-i;
            if(other<0)break;
            
            
//看报错:
            /*
对应输出应该为:
314 500
你的输出为:
312 502
困扰好久,代码肯定没错,也就是说有312 502的硬币是有的,那为什么答案是314 500.
没考虑到硬币最大500!
而数组越界没有报错!判断为有502这个硬币!
    原来是少了这个条件
            if(other > 500){
             continue;
         }
*/
            
            if(other==i){
                if(coinNums[other]>1){
                    cout<<i<<" "<<other<<endl;
                    return 0;
                }
            }else{
                if(coinNums[other]>0){
                    cout<<i<<" "<<other<<endl;
                    return 0;
                }
            }
        }
    }
     
    cout<<"No Solution"<<endl;
    return 0;
}

发表于 2017-07-21 16:19:40 回复(0)
散列好,不超时。
#include<bits/stdc++.h>
using namespace std;

int hashtable[1010];

int main() {
        ios::sync_with_stdio(0);
	int n,m,a;
	cin>>n>>m;
	for(int i=0; i<n; i++) {
		cin>>a;
		hashtable[a]++;
	}
	bool flag=0;
	for(int i=0; i<510; i++) {
		if(hashtable[i]&&hashtable[m-i]) {
			if(i==m-i&&hashtable[i]>1) {
				continue;
			}
			cout<<i<<" "<<m-i<<endl;
			flag=1;
			break;
		}
	}
	if(!flag) cout<<"No Solution"<<endl;
	return 0;
}

编辑于 2022-11-11 14:55:45 回复(6)
y总那来的,可以考虑把《数组元素的目标和》这部分的代码移植到这道题上,
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 100010;

int main()
{
    int n,x;
    cin >> n >> x;
    int a[N];
    for(int i = 0;i <n;i++) cin >>a[i];
    
    sort(a,a+n);
    int i = 0;
    int j= n-1;

    while(i<n){
        while(j>=0 && a[i]+a[j]>x) j--;
        if(a[i] + a[j] == x){
            break;
        }
        i++;
    }


    if(i>=n) cout << "No Solution";
    else{
        if(a[i]<a[j]) cout << a[i] <<' '<<a[j];
        else cout << a[j] <<' '<<a[i];
    }
}


发表于 2022-05-07 15:57:27 回复(0)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
    int n,pay;
    cin>>n>>pay;
    vector<int> v;
    v.resize(n);
    for(int i=0;i<n;i++)
        cin>>v[i];
    sort(v.begin(),v.end());
    int v1=-1,v2=-1;
    for(int i=0;i<n;i++)
    {
        int target=pay-v[i];
        int left=i+1;
        int right=n-1;
        while(left<=right)
        {
            int mid=(left+right)/2;
            if(v[mid]==target)
            {
                v1=v[i];
                v2=v[mid];
                break;
            }
            else if(v[mid]>target)
                right=mid-1;
            else
                left=mid+1;
        }
        if(v1>0&&v2>0)
            break;
    }
    if(v1>0&&v2>0)
        cout<<v1<<" "<<v2;
    else cout<<"No Solution";
}
二分查找
发表于 2020-08-29 23:23:51 回复(0)
//开始用dfs,超时
//然后遍历,去除掉大于pay的值,还是超时
//从首尾向中间遍历就可以了
#include<iostream>
(720)#include<vector>
#include<algorithm>
using namespace std;
vector<int>coins;
int n, x, pay;
int main() {
	cin >> n >> pay;
	for (int i = 0; i < n; i++) {
		cin >> x;
		coins.push_back(x);
	}
	sort(coins.begin(), coins.end(), less<int>());
	int i = 0, j = n - 1;
	while (i < j) {
		if (coins[i] + coins[j] > pay) { j--; }
		else if (coins[i] + coins[j] == pay) {
			printf("%d %d", coins[i], coins[j]);
			return 0;
		}
		else {
			i++;
		}
	}
	printf("No Solution");
}


发表于 2020-03-25 14:23:11 回复(0)
#include <iostream>
(720)#include <stdio.h>
#include <vector>
(721)#include <map>
#include <algorithm>
using namespace std;

int main()
{
	int n , m;
	scanf("%d%d", &n , &m);
	vector<int> coins(n);
	map<int, int> remark;
	for(int i = 0; i < n ; i++)
	{
		scanf("%d", &coins[i]);
		if(remark.count(coins[i]) == 0)
			remark[coins[i]] = 1;
		else
			remark[coins[i]]++;
	}
	sort(coins.begin(), coins.end());
	for(int i = 0; i < n; i++)
	{
		if(coins[i] * 2 == m && remark[coins[i]] == 1)
			continue;
		if(remark.count(m - coins[i]) != 0)
		{
			printf("%d %d\n", coins[i], m - coins[i]);
			return 0;
		}
	}
	printf("No Solution\n");
	return 0;
}
不小心排名第一,嘻嘻嘻
发表于 2020-03-10 18:25:04 回复(0)
//1048 Find Coins (25分)
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
int hashTable[501] = { 0 };//硬币面值不超过500
int main()
{
    int n, amount;
    scanf("%d%d", &n,&amount);
    while (n--)
    {
        int temp;
        scanf("%d", &temp);
        hashTable[temp]++;
    }
    for (int i = 1; i<=amount; i++) {//为何i<=amount&&amount-i<=500就不对?
        if (amount - i <= 500)
        if (hashTable[i] && hashTable[amount - i]) {
            if (2 * i == amount && hashTable[i] < 2) {
                continue;
            }
            printf("%d %d\n", i, amount - i);
            return 0;
        }
    }
    printf("No Solution\n");
    return 0;
}
为何i<=amount&&amount-i<=500就不对???逻辑上来说和下面是等价的


编辑于 2020-02-11 12:52:59 回复(0)

就是把每种情况都枚举到就行

#include<iostream>
#include<stdlib.h>
#include<vector>
#include<algorithm>
using namespace std;

int main() {
    vector<int> num;
    int n = 0, m = 0,tem = 0,first = 0,last = 0;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        scanf("%d",&tem);
        num.push_back(tem);
    }
    sort(num.begin(), num.end());
    int index = lower_bound(num.begin(), num.begin()+n, m) - num.begin();//找到第一个大于等于m的
    num.erase(num.begin() + index, num.end());//去除大于等于m的数
    for (first = 0, last = num.size() - 1; first < last; ) {
        if (num[first] + num[last] == m) {
            break;
        }
        else if(num[first] + num[last] < m){
            first++;
        }
        else {
            last--;
        }
    }
    if (first < last) {
        cout << num[first] << " " << num[last] << endl;
    }
    else {
        cout << "No Solution" << endl;
    }
    system("pause");
    return 0;
}
编辑于 2019-10-21 21:56:19 回复(0)
非常简单的一道题,直接看代码便能明白我的思路


#include<iostream>
#include<stdio.h>
using namespace std;
const int maxn = 100009;
int coin[maxn];    //coin[i] mean the number of coin with value i
int cnum, amount;
int main(){
    //get input data
    cin >> cnum >> amount;
    for (int i = 0; i < cnum; i++){
        int value;
        scanf("%d", &value);
        coin[value]++;
    }
    //find the answer
    int coin1 = -1; //the first coin value, -1 mean no answer
    for (int i = 1; i < maxn; i++){    //i mean value, coin[i] mean munber of coin with value i
        if (coin[i] == 0) continue;    //not have it value
        int res = amount - i;
        if (i > res) break;    //already checked
        if (res == i){    //need two same vlue coins
            if (coin[res]  < 2 ) continue;
            coin1 = i;
            break;
        }
        if (coin[res] > 0){//need two different coins
            coin1 = i;
            break;
        }
    }
    if (coin1 == -1) cout << "No Solution" << endl;
    else cout << coin1 << " " << amount - coin1 << endl;
}



编辑于 2019-04-09 09:53:45 回复(0)
java是真的慢呀
发表于 2018-10-23 21:43:20 回复(0)
N,M=map(int,input().split())
L=list(map(int,input().split()))
L.sort()
res=[]
for i in range(N):
    lo,hi=i+1,N
    while hi-lo>1:
        mid=(lo+hi)//2
        if L[mid]+L[i]==M:
            res=[L[i],L[mid]]
            break
        elif L[mid]+L[i]<M:
            lo=mid+1
        else:
            hi=mid
    if res:
        print(' '.join(map(str,res)))
        break
else:
    print('No Solution')

发表于 2018-09-04 07:44:52 回复(0)