pat甲级1048. Find Coins (25)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/richenyunqi/article/details/79944984

欢迎访问我的pat甲级题解目录哦https://blog.csdn.net/richenyunqi/article/details/79958195

1048. Find Coins (25)

时间限制
100 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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.

Input Specification:

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.

Output Specification:

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.

Sample Input 1:
8 15
1 2 8 7 2 4 11 15
Sample Output 1:
4 11
Sample Input 2:
7 14
1 8 7 2 4 11 15
Sample Output 2:
No Solution

3种方法:

1、二分查找

算法设计:

将输入的数据存储在长度为N的数组A中,将A数组元素从小到大进行排序,遍历整个数组,对于遍历到的元素A[i],在[i+1,N)中利用二分查找算法查找是否有M-A[i]这个数,有则按要求进行输出;如果数组遍历完仍然没有找到,则输出"No Solution"

c++代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int N,M;
    scanf("%d%d",&N,&M);
    int A[N];
    for(int i=0;i<N;++i)
        scanf("%d",&A[i]);
    sort(A,A+N);
    for(int i=0;i<N;++i){
        if(binary_search(A+i+1,A+N,M-A[i])){
            printf("%d %d",A[i],M-A[i]);
            return 0;
        }
    }
    printf("No Solution");
    return 0;
}

2、two pointers

算法设计:

将输入的数据存储在长度为N的数组A中,将A数组元素从小到大进行排序,定义两个索引 i=0、j=N-1,如果i<j则进行循环并进行以下判断:

  1. 如果A[i]+A[j]>M,令 j 左移一位,--j
  2. 如果A[i]+A[j]<M,令 i 右移一位,++i
  3. 如果A[i]+A[j]==M,说明找到了一组符合要求的两个数,输出,退出循环

如果当i<j退出循环时仍然没有找到符合要求的两个数,则输出"No Solution"

c++代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int N,M;
    scanf("%d%d",&N,&M);
    int A[N];
    for(int i=0;i<N;++i)
        scanf("%d",&A[i]);
    sort(A,A+N);
    for(int i=0,j=N-1;i<j;)
        if(A[i]+A[j]>M)
            --j;
        else if(A[i]+A[j]<M)
            ++i;
        else{
            printf("%d %d",A[i],A[j]);
            return 0;
        }
    printf("No Solution");
    return 0;
}

3、散列

算法设计:

定义一个map<int,int>类型变量,键存储输入的数据,值存储该数据出现了几次。遍历整个map,如果出现下列任何一种情况就说明找到了符合要求的两个数,直接进行输出:

  1. 遍历到的键是M的一半且遍历到的值>=2
  2. 遍历到的键不是M的一半且M减去该键得到的数在map中能够找到与之相等的键

如果map遍历完仍然没有找到符合要求的两个数,则输出"No Solution"

c++代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int N,M;
    scanf("%d%d",&N,&M);
    map<int,int>m;
    while(N--){
        int a;
        scanf("%d",&a);
        ++m[a];
    }
    for(auto i=m.cbegin();i!=m.cend();++i){
        if((M-i->first==i->first&&i->second>=2)||(M-i->first!=i->first&&m.find(M-i->first)!=m.cend())){
            printf("%d %d",i->first,M-i->first);
            return 0;
        }
    }
    printf("No Solution");
    return 0;
}

阅读更多

扫码向博主提问

日沉云起

用最短的代码,写最快的算法
  • 擅长领域:
  • 算法
去开通我的Chat快问
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页