PAT A1048 Find Coins (25 分) __hash || 二分 || two pointers

题目要求:

给出 正整数m和n个正整数(num1,num2,…,num n),让你求出( num i + num j ==m)的方案,若方案不唯一,要求输出num i 最小的方案。

三种方法:

  1. 用hashTable记录每个数字出现的次数,从i开始枚举,如果hashTable[i[>0&&hashTable[j]>0&&(i+j>=2),则输出。(要注意i=j且次数等于1的情况)
  2. 排序+二分,用 lower_bound函数。
  3. two pointers

方法一:hashTable:

#include<cstdio>
#include<algorithm>
using namespace std;

int const MAXN = 100010,MAXM = 1010;
int hashTable[MAXM] = {0};

int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	
	for(int i=0;i<n;i++)
	{
		int t;
		scanf("%d",&t);
		hashTable[t]++;
	}

	for(int i=0;i<m;i++)
	{
		if(hashTable[i]>0&&hashTable[m-i]>0)
		{
			if(i==m-i&&hashTable[i]<2)
				continue;
			printf("%d %d",i,m-i);
			return 0;
		}
	}
	
	printf("No Solution");
	return 0;
}

方法二:二分

/*Sample Input 1:
8 15
1 2 8 7 2 4 11 15----------------
4 11
Sample Input 2:
7 14
1 8 7 2 4 11 15---------------
No Solution*/

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxn = 100010;
int n,m;
int a[maxn] = {0};

int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);

    sort(a,a+n);

    for(int i=0;i<n;i++)
    {
        //二分法查找第一个大于等于m-a[i]的数字
        int t=a[i];
        int* j = lower_bound(a+i+1,a+n,m-t);
        if(a[i]+*j==m&&i!=n-1)
        {
            printf("%d %d",a[i],*j);
            return 0;
        }
    }

    printf("No Solution");

    return 0;
}

方法3:two pointers

/*Sample Input 1:
8 15
1 2 8 7 2 4 11 15
Sample Output 1:
4 11*/
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxn = 100010;
int a[maxn]={0};

int main()
{
    int n,m;
    cin>>n>>m;

    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);

    sort(a,a+n);

    int i=0,j=n-1;
    while(i<j)
    {
        if(a[i]+a[j]==m)
        {
            cout<<a[i]<<" "<<a[j];
            return 0;
        }
        if(a[i]+a[j]<m)
            i++;
        else if(a[i]+a[j]>m)
            j--;
    }
    cout<<"No Solution";


    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值