PAT甲級 1048 Find Coins(二分/map 來查找是否有硬幣之和恰好爲m)

1.map容器

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

typedef long long ll;
const int maxn = 100000 + 5;
map<int, int> mark;
int num[maxn];

int cmp(int a, int b){
    return a < b;
}

int main(){
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; i++){
        scanf("%d", &num[i]);
        if(mark[num[i]]) mark[num[i]]++;
        else mark[num[i]] = 1;
    }
    sort(num, num+n, cmp);
    for(int i = 0; i < n && num[i] <= m/2; i++){
        int x = num[i];
        if(mark[m - x]){
            if(x + x != m){
                printf("%d %d", x, m-x);
                return 0;
            }
            else if(mark[x] > 1){
                printf("%d %d", x, m-x);
                return 0;
            }
        }
    }
    printf("No Solution");
    return 0;
}

2.二分查找

1)upper_boud(a, a+n, x) : 在a[0]到a[n-1]中查找第一個大於x的值
#include <iostream>
#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;

typedef long long ll;
const int maxn = 100000 + 5;
int num[maxn];

int cmp(int a, int b){
    return a < b;
}

int main(){
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; i++){
        scanf("%d", &num[i]);
    }
    sort(num, num+n, cmp);
    for(int i = 0; i < n && num[i] <= m/2; i++){
        int x = num[i];
        int j = upper_bound(num+i+2, num+n, m-x) - num;
        //爲了防止重複,要從Num+i+2開始查找比該值大的值!(即num[i+2],這樣至少找到的值是num[i+1]而非Num[i]
        //upper_bound從begin,end-1位置查找
        if(j <= n && num[j-1] == m - x){
            printf("%d %d", x, m-x);
            return 0;
        }
    }
    printf("No Solution");
    return 0;
}

2)手寫二分
#include <iostream>
#include<cstdio>
#include<map>
#include<algorithm>
using namespace std;

typedef long long ll;
const int maxn = 100000 + 5;
int num[maxn];

int cmp(int a, int b){
    return a < b;
}
//找到區間內是否有值爲x的元素
int Binary(int l, int r, int x){
    while(l <= r){
        int mid = (l + r)/2;
        if(num[mid] == x){
            return mid;
        }
        if(num[mid] < x){
            l = mid + 1;
        }
        else if(num[mid] > x){
            r = mid - 1;
        }
    }
    return -1;
}

int main(){
    int n, m;
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; i++){
        scanf("%d", &num[i]);
    }
    sort(num, num+n, cmp);
    for(int i = 0; i < n && num[i] <= m/2; i++){
        int x = num[i];
        int j = Binary(i+1, n-1, m-x);
        //爲了防止重複,要從Num+i+2開始查找比該值大的值!(即num[i+2],這樣至少找到的值是num[i+1]而非Num[i]
        //upper_bound從begin,end-1位置查找
        if(j != -1){
            printf("%d %d", x, m-x);
            return 0;
        }
    }
    printf("No Solution");
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章