PAT.A1048 Find Coins

返回目录

在这里插入图片描述

题意

给出n个正整数和一个正整数m, 间n个数字中是否存在一对数字a和b(a≤b), 使得a+b=m成立。如果有多对,输出a最小的那一对。

样例(可复制)

8 15
1 2 8 7 2 4 11 15

样例输出

4 11

注意点

  1. 本题提供3种解决办法:散列法、二分法和two pointers
  2. 使用散列法时:map的大小不需要很大,也不能像500这么小,比1000大点就好了,如果map只开到500这么大,那map[m-i]会发生越界,测试点报段错误
  3. 使用二分法时:找到第一个大于等于m-num[i]位置j时,要判断当前的j是否就是i,如果是,需要跳过这种情况

散列法

#include <bits/stdc++.h>
using namespace std;

int main(){
    int n,m,map[1010]={0};
    cin>>n>>m;
    while(n--){
        int tmp;
        scanf("%d",&tmp);
        if(tmp>m)continue;
        map[tmp]++;
    }
    int i;
    for(i=1;i<1000;i++){
        if(2*i==m&&map[i]>=2){
            cout<<i<<" "<<m-i;break;
        }
        if(map[i]&&map[m-i]&&2*i!=m){
            cout<<i<<" "<<m-i;break;
        }
    }
    if(i==1000)cout<<"No Solution";
	return 0;
}

二分法

#include <bits/stdc++.h>
using namespace std;

int main(){
    int n,m;
    cin>>n>>m;
    int num[100010];
    for(int i=0;i<n;i++)scanf("%d",&num[i]);
    sort(num,num+n);
    int i;
    for(i=0;i<n;i++){
        int j=lower_bound(num,num+n,m-num[i])-num;
        if(i==j)continue;
        if(num[i]+num[j]==m){
            cout<<num[i]<<" "<<num[j];break;
        }
    }
    if(i==n)cout<<"No Solution";
	return 0;
}

two pointers

#include <bits/stdc++.h>
using namespace std;

int main(){
    int n,m;
    cin>>n>>m;
    int num[100010];
    for(int i=0;i<n;i++)scanf("%d",&num[i]);
    sort(num,num+n);
    int i=0,j=n-1;
    while(i<j){
        if(num[i]+num[j]==m){
            cout<<num[i]<<" "<<num[j];
            return 0;
        }
        if(num[i]+num[j]>m)j--;
        else if(num[i]+num[j]<m)i++;
    }
    cout<<"No Solution";
	return 0;
}
发布了137 篇原创文章 · 获赞 4 · 访问量 6035

猜你喜欢

转载自blog.csdn.net/a1920993165/article/details/105290087