PAT_甲级_1048 Find Coins

码上飞
• 阅读 976

题目大意:

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

算法思路1:

使用hash散列的思想来处理每一个输入的数字,nums来记录每一个数字出现的次数,下标为数字,其值为出现次数。那么我们从0开始遍历一直到1000,对于每一个数字j,首先得判断j和M-j出现的次数是否都不为0,如果是,对于所有j!=M-j(两数字不相等)或者j==M-j并且nums[j]>1(两数字相等但是出现了至少2次),就输出j和M-j,并且结束程序即可。如果遍历完毕,输出No Solution

算法思路2:

使用二分查找的思想解决该问题,首先,使用coins数组存储所有的货币,然后对其从小到大排序,遍历每一个coins[j],在数组中查找M-coins[j],如果存在,并且其位置pos不等于j,就输出coins[j]和M-coins[j],并且退出循环。如果遍历完毕,输出No Solution.

算法思路3:

同样使用coins数组存储所有的货币,然后对其从小到达排序。然后使用指针i指向0,指针j指向N-1,然后i向右走,j向左走,如果i和j指向的数字之和sum等于M,就输出coins[i]和coins[j]然后结束程序,如果sum<M,说明coins[i]太小,那么就让i向右走一格,否则说coins[j]太大,就让j向左走一格。如果遍历完毕,输出No Solution

注意点:

1、得将nums数组写在main函数外面,不然测试点1报错。
2、得考虑2个数字相等的情况,不然测试点1报错。
3、二分法的二分函数得写在main函数外,不然测试点1和2会运行超时。
4、个人推荐算法思路3,无需考虑2个数字相等

提交结果:

PAT_甲级_1048 Find Coins

AC代码1:

#include <cstdio>

using namespace std;

int nums[1001];// 得写在main函数外面
int main()
{
    int N,M;
    scanf("%d %d",&N,&M);
    int temp;
    for (int i = 0; i < N; ++i) {
        scanf("%d",&temp);
        ++nums[temp];
    }
    for (int j = 0; j < 1001; ++j) {
        if(nums[j]!=0&&nums[M-j]!=0){
            if(j!=M-j||(2*j==M&&nums[j]>1)){
                printf("%d %d",j,M-j);
                return 0;
            }
        }
    }
    printf("No Solution");
    return 0;
}

AC代码2:

#include <cstdio>
#include <algorithm>

using namespace std;

int binarySearch(int left,int right,int num,const int coins[]){
    int mid;
    while (left<=right){
        mid = left + (right-left)/2;
        if(coins[mid]==num){
            return mid;
        } else if (coins[mid]<num){
            left = mid+1;
        } else {
            right = mid-1;
        }
    }
    return -1;
}

int main(){
    int N,M;
    scanf("%d %d",&N,&M);
    int coins[N];
    for(int i=0;i<N;++i){
        scanf("%d",&coins[i]);
    }
    sort(coins,coins+N);
    for (int j = 0; j < N; ++j) {
        //对于coins[j],查找M-coins[j]==coins[k]的k并且k!=j
        int mid;
        int pos = binarySearch(0,N-1,M-coins[j],coins);
        if(pos!=-1&&pos!=j){
            printf("%d %d",coins[j],coins[pos]);
            return 0;
        }
    }
    printf("No Solution");
    return 0;
}

AC代码3:

#include <cstdio>
#include <algorithm>

using namespace std;

int main(){
    int N,M;
    scanf("%d %d",&N,&M);
    int coins[N];
    for(int i=0;i<N;++i){
        scanf("%d",&coins[i]);
    }
    sort(coins,coins+N);
    int i=0,j=N-1;
    while (i<j){
        if(coins[i]+coins[j]==M){
            printf("%d %d",coins[i],coins[j]);
            return 0;
        } else if(coins[i]+coins[j]<M){
            ++i;
        } else {
            --j;
        }
    }
    printf("No Solution");
    return 0;
}
点赞
收藏
评论区
推荐文章
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Wesley13 Wesley13
3年前
PTA 7
将一系列给定数字顺序插入一个初始为空的二叉搜索树(定义为左子树键值大,右子树键值小),你需要判断最后的树是否一棵完全二叉树,并且给出其层序遍历的结果。输入格式:输入第一行给出一个不超过20的正整数N;第二行给出N个互不相同的正整数,其间以空格分隔。输出格式:将输入的N个正整数顺序插入一个初始为空的二叉搜索树。在第一
DaLongggggg DaLongggggg
4年前
python刷题-特殊回文数
问题描述  123321是一个非常特殊的数,它从左边读和从右边读是一样的。  输入一个正整数n,编程求所有这样的五位和六位十进制数,满足各位数字之和等于n。输入格式  输入一行,包含一个正整数n。输出格式  按从小到大的顺序输出满足条件的整数,每个整数占一行。样例输入52样例输出899998989989998899数据规模和约定 
DaLongggggg DaLongggggg
4年前
python刷题-最大最小公倍数
问题描述已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。输入格式输入一个正整数N。输出格式输出一个整数,表示你找到的最小公倍数。样例输入9样例输出504数据规模与约定1<N<106。Nint(input())Min1ifN<2:print(N)elifN%2
DaLongggggg DaLongggggg
4年前
python-阶乘计算
问题描述  输入一个正整数n,输出n的值。  其中n123…n。算法描述  n可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A0表示a的个位,A1表示a的十位,依次类推。  将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。  首先将a设为1,然后乘2,
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
PAT 1065 单身狗(25)(STL
1065 单身狗(25 分)“单身狗”是中文对于单身人士的一种爱称。本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱。输入格式:输入第一行给出一个正整数N(≤ 50000),是已知夫妻/伴侣的对数;随后N行,每行给出一对夫妻/伴侣——为方便起见,每人对应一个ID号,为5位数字(从00000到99999),
Stella981 Stella981
3年前
LeetCode 5561. 获取生成数组中的最大值
文章目录1\.题目2\.解题1\.题目给你一个整数n。按下述规则生成一个长度为n1的数组nums:nums00nums11当2<2i<n时,nums2inumsi
Wesley13 Wesley13
3年前
1050 螺旋矩阵
1050 螺旋矩阵 (25分)本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第1个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。输入格式:输入在第1行中给出一个正整数 N,第2行给出 N
Wesley13 Wesley13
3年前
PAT
ps:真不明白为什么水题不能一次ac714 电话聊天狂人(25 分)给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人。输入格式:输入首先给出正整数N(≤10​5​​),为通话记录条数。随后N行,每行给出一条通话记录。简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔。输出格式
贾蔷 贾蔷
3星期前
NOIP 2000 提高组 洛谷1004题(方格取数)解题思路与C++代码解析
一、题目描述简要描述题目:例如,在一个n×n的方格图中,每个格子包含一个正整数。需要选择两条从左上角到右下角的路径,路径可重复经过格子,但两条路径除起点和终点外不能相交。求两条路径数字和的最大值。二、解题思路与算法分析1.问题分析1.问题核心是求解两条不交