PAT-A 1048. Find Coins (25)
来源:互联网 发布:苹果打开数据的快捷键 编辑:程序博客网 时间:2024/06/18 14:29
题目链接在此。
该题解题记录目前有:散列hashTable方法、二分查找方法、Two pointers法。
题意
给定两个整数N,M,给出N个硬币的面值(面值<=500),问是否存在两枚硬币v1,v2,是的v1+v2==M,并且v1<=v2。如果答案不唯一,输出a最小的那一对。
散列hashTable方法
思路
定义一个hashTable数组用来记录每种面值硬币的个数
v1从1开始枚举到m/2+1(因为再往后就没有必要了,那样只是v1和v2的值对调了一下),hashTable[v1]–(主要为v1==v2的情况服务),如果hashTable[M-v1] >0则说明存在,否则查询v1的下一个。
AC代码
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int main(){ int N,pay; scanf("%d %d",&N, &pay); int hashTable[1001] = {0}; //注意hashTable的大小 int temp; for(int i = 0; i < N; i++){ scanf("%d",&temp); hashTable[temp]++; } int v1; for(v1 = 1; v1 < pay/2+1; v1++){ if(hashTable[v1] > 0){ //有v1面值的coin hashTable[v1]--; //v1面值的-1 int v2 = pay - v1; if(hashTable[v2] > 0){ //有和v1对应的v2的面值的coin,则可以凑成 printf("%d %d\n",v1,v2); break; } } } if(v1 >= pay/2+1){ //没找到符合题意的 printf("No Solution\n"); } return 0;}
二分查找法
思路
用数组a[]保存输入,之后i从0~n-1枚举每个数,然后对0~n-1这个区间内的元素做二分查找,找到一个即可输出然后退出循环。
注意:二分查找需要序列有序。
AC代码
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int a[100010]; //二分查找数组a[]的left到right区间内a[mid] == x int binary_search(int left, int right, int x){ while(left <= right){ int mid = (left+right)/2; if(a[mid] == x){ return mid; }else if(a[mid] > x){ right = mid - 1; }else { //a[mid] < x left = mid + 1; } } return -1; } int main(){ int n,pay; scanf("%d %d",&n,&pay); bool flag = false; int v1 = 1000 , v2; for(int i = 0; i < n; i++){ scanf("%d",a+i); } sort(a,a+n); //二分查找的前提是有序 int i; for(i = 0; i < n; i++){ int ans = binary_search(0,n-1,pay-a[i]); //查找i~n-1的序列中,a[i]等于pay-a[1](即v2)的值 if(ans != -1 && ans != i){ //注意:返回的结果是本元素的情况不是能要的 printf("%d %d\n",a[i],a[ans]); break; //只需要输出v1最小的,由于已经从小到大排序,所以输出一个即可退出 } } if(i == n){ //没有找到符合要求的元素 printf("No Solution\n"); } return 0; }
two pointers 法
思路
- 先用sort排序
- 用两个指针i,j分别指向排序之后的数组的首尾端
a[i]+a[j] == pay,输出结果,退出循环
a[i]+a[j] > pay,j–
a[i]+a[j] < pay,i++ - 判断是否已经输出了结果,没有输出则表示没知道到合适的解,输出”No solution”
AC代码
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int main(){ int n,pay; scanf("%d %d",&n,&pay); int a[100010]; for(int i = 0; i < n; i++){ scanf("%d",&a[i]); } sort(a,a+n); bool flag = false; int i = 0,j = n-1; while( i < n && j >= 0){ int sum = a[i]+a[j]; if(sum == pay && i!=j){ //注意i!=j printf("%d %d",a[i],a[j]); flag = true; break; }else if(sum < pay){ i++; }else{ j--; } } if(flag == false) printf("No Solution\n"); return 0;}
也可以写成这样:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int main(){ int n,pay; scanf("%d %d",&n,&pay); int a[100010]; for(int i = 0; i < n; i++){ scanf("%d",&a[i]); } sort(a,a+n); int i = 0,j = n-1; while( i < j){ int sum = a[i]+a[j]; if(sum == pay){ //注意i!=j printf("%d %d",a[i],a[j]); break; }else if(sum < pay){ i++; }else{ j--; } } if(i == j){ printf("No Solution\n"); } return 0;}
0 0
- PAT(A) - 1048. Find Coins (25)
- PAT-A 1048. Find Coins (25)
- PAT-A-1048. Find Coins (25)
- PAT-A 1048. Find Coins
- 1048. Find Coins (25)-PAT
- 【PAT】1048. Find Coins (25)
- PAT 1048. Find Coins (25)
- pat 1048. Find Coins (25)
- PAT 1048. Find Coins (25)
- PAT 1048. Find Coins (25)
- pat 1048. Find Coins (25)
- PAT 1048.Find Coins
- 【PAT】1048. Find Coins
- PAT--1048. Find Coins
- PAT 1048. Find Coins
- PAT-Find Coins (25)
- PAT (Advanced) 1048. Find Coins (25)
- PAT甲 1048. Find Coins (25)
- 求最大子序列和的分而治之算法
- kaka Ask 咖咖问
- PAT-A1069
- 安卓手机号和邮箱正则表达验证
- NQSky-前世今生
- PAT-A 1048. Find Coins (25)
- extern问题
- JQuery常用操作
- 53. Maximum Subarray LeetCode
- TensorFlow之卷积
- C#开发命名规范
- 光电编码器简介
- Android ListView长按多选模式
- HBase写性能优化策略