c_pat_漏掉的数字 & 找硬币(思维题)

be unique

给定 N 个整数,请你找出最小的不在给定整数列表中的正整数。
\(N<10^5\)

思路
由于 N 小于1e5,可以直接从1遍历到max_element(A),为什么呢?即使最大的数是INT_MAX,数组最多只会遍历1e5次(1...9999),而不会遍历2e11次;这是最暴力的做法;

能不能别这么暴力?找到所有正数,如果 A[i-1]+1≠A[i] && A[i-1]!=A[i] 则证明缺失的是 A[i-1]+1

#include<bits/stdc++.h>
using namespace std;
int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int n, x; cin>>n;
    vector<int> A;
    for (int i=0; i<n; i++) {
        cin>>x; if (x>0) A.emplace_back(x);
    }
    if (A.empty()) {
        cout<<1;
    } else {
        sort(A.begin(), A.end());
        bool found=0;
        for (int i=1; i<A.size(); i++) if (A[i-1]+1!=A[i] && A[i-1]!=A[i]) {
            found=1;
            cout<<A[i-1]+1;
            break;
        }
        if (!found) cout<<A.back()+1;
    }
    return 0;
}

Find Coins

给定她拥有的所有硬币的面额,请你帮她确定对于给定的金额,她是否可以找到两个硬币V1、V2来支付。
如果答案不唯一,则输出 V1 最小的解。

思路
讨论 m-x 是否和 x 相同:

  • 如果相同的话,在序列中出现的次数就要多于1次;
  • 否则只需判断 m-x 是否出现过即可
#include<bits/stdc++.h>
using namespace std;

int main() {
    std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int n, m; cin>>n>>m;
    unordered_map<int, int> cnt;
    int A[n]; for (int i=0; i<n; i++) cin>>A[i], cnt[A[i]]++;
    sort(A, A+n);
    for (int x : A) {
        int k=m-x;
        if (cnt.find(k)!=cnt.end() && (k==x && cnt[x]>1 || k!=x && cnt[x]>0)) {
            return cout<<min(x,k)<<' '<<max(k,x), 0;
        }
    }
    cout<<"No Solution";
    return 0;
}
posted @ 2020-09-23 10:33  童年の波鞋  阅读(130)  评论(0编辑  收藏  举报