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;
}