目录
1149 Dangerous Goods Packaging
1145 Hashing - Average Search Time
1048 Find Coins
解析
法一:hash表
1.用一个哈希表存储硬币,对于每一枚硬币 x,判断在集合中是否存在 y,使得 x + y = m。
2.如果存在,则是一组解,判断该解的小面值硬币是否小于 v1, 如果是,则存入 v1, v2。
如果存在解,则输出。否则无解。
注意点
先判断再插入,效率比较高
#include <iostream>
#include <unordered_set>
using namespace std;
int main(){
int n, m;
cin >> n >> m;
unordered_set<int> S; //存储数据的哈希表
int v1 = 1e9, v2; //v1 设置一个较大的值
for (int i = 0; i < n; i ++ ){
int x;
cin >> x;
int y = m - x; //x + y = m,对于输入的 x,在堆中查看有没有 y。
if (S.count(y)){
S.insert(x);
if (x > y) swap(x, y);
if (x < v1) v1 = x, v2 = y; //判断该解的小面值是否小于 v1,如果是,则把该解存入 v1, v2.
}
else S.insert(x);
}
if (v1 == 1e9) puts("No Solution");
else cout << v1 << ' ' << v2 << endl;
return 0;
}
法二:双指针
解析
1.先排序
2.左指 l 针指向数组头,右指针 r 指向数组尾。
如果 a[l] + a[r] > m , 则 r 左移。
如果 a[l] + a[r] < m , 则 l 右移。
如果 a[l] + a[r] = m , 则找到解。
如果指针相遇还没有出现 a[l] + a[r] = m ,则无解。
注意点
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int ans[N];
int main(){
int n, m;
cin >> n >> m;
int v1 = -1, v2 = -1;
for(int i = 0; i < n; i++){
int x;
cin >> ans[i];
}
sort(ans, ans + n); //双指针需要先排序
int l = 0, r = n - 1; //l 左指针,r 右指针
while(l < r){ //指针未相遇就一直执行
if(ans[l] + ans[r] == m){ //找到答案
v1 = ans[l];
v2 = ans[r];
break;
}else if(ans[l] + ans[r] > m){ //两数之和大于 m, 则右指针左移
r--;
}else{ //两数之和小于 m, 则做指针右移
l++;
}
}
if(v1 >= 1){ //v1 大于 1 说明找到了解
cout << v1 << " " << v2;
}else{
cout << "No Solution";
}
return 0;
}
1063 Set Similarity
解析:
Nc:两个集合交集的元素数量
Nt:两个集合并集的元素数量
注意点:最后输出% 要在printf里加两个%%
(double)nc / nt * 100
#include <iostream>
#include <unordered_set>
using namespace std;
const int N = 55;
int n;
unordered_set<int> S[N];
int main(){
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ){
int m;
scanf("%d", &m);
while (m -- ){
int x;
scanf("%d", &x);
S[i].insert(x);
}
}
int k;
scanf("%d", &k);
while (k -- ){
int a, b;
scanf("%d%d", &a, &b);
int nc = 0;
for (auto x : S[a]) nc += S[b].count(x);
int nt = S[a].size() + S[b].size() - nc;
printf("%.1lf%%\n", (double)nc / nt * 100);
}
return 0;
}
1120 Friend Numbers
注意点
1. 有顺序的输出,所以不用unordered_set
2.如何分解数的每一位, 高精度思想
#include<iostream>
#include<set>
using namespace std;
int main(){
int n;
cin >> n;
set<int> S; //set自动排序
while(n--){
int x;
cin >> x;
int s = 0;
while(x != 0) s += x % 10, x /= 10; //如何分解每一位
S.insert(s);
}
cout << S.size() << endl;
bool flag = true;
for(auto x : S){
if(flag) flag = false; //如何处理最后多一个空格
else cout << " ";
cout << x;
}
return 0;
}
1144 The Missing Number
解析
注意点
1.最后一组数据 有个20000000 用数组当哈希表会出现段错误
#include <iostream>
#include <unordered_set>
using namespace std;
int main(){
int n;
cin >> n;
unordered_set<int> S;
while (n -- ){
int x;
cin >> x;
S.insert(x);
}
int res = 1;
while (S.count(res)) res ++ ;
cout << res << endl;
return 0;
}
用数组当哈希表
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int a[N] = {0};
int main(){
int n;
cin >> n;
while(n--){
int x;
cin >> x;
if(x > 0 && x < N){
a[x]++;
}
}
for(int i = 1; i < N; i++){
if(a[i] == 0){
cout << i;
break;
}
}
return 0;
}
1149 Dangerous Goods Packaging
解析
注意点
#include<iostream>
#include<cstring>
#include<unordered_set>
using namespace std;
#define x first //把first定义为x
#define y second //把second定义为y
typedef pair<int,int> PII; //出现一对的时候很好用
const int N = 10010;
PII a[N];
int main(){
int n, m;
cin >> n >> m;
for(int i = 0; i < n; i ++){
cin >> a[i].x >> a[i].y;
}
while(m--){
unordered_set<int> S;
int k;
cin >> k;
for(int i = 0; i < k; i ++){
int x;
cin >> x;
S.insert(x);
}
bool flag = true;
for(int i = 0; i < n; i ++){
if(S.count(a[i].x) && S.count(a[i].y)){ //遍历每个限制对,看有没有出现其中的某一个
flag = false;
break;
}
}
if(flag) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
1078 Hashing
#include <iostream>
using namespace std;
const int N = 10010;
int s, n;
int h[N];
bool is_prime(int x){
if (x == 1) return false;
for (int i = 2; i * i <= x; i ++ )
if (x % i == 0)
return false;
return true;
}
int find(int x){
int t = x % s;
for (int k = 0; k < s; k ++ )
{
int i = (t + k * k) % s;
if (!h[i]) return i;
}
return -1;
}
int main(){
cin >> s >> n;
while (!is_prime(s)) s ++ ;
for (int i = 0; i < n; i ++ ){
int x;
cin >> x;
int t = find(x);
if (t == -1) printf("-");
else{
h[t] = x;
printf("%d", t);
}
if (i != n - 1) printf(" ");
}
return 0;
}
1145 Hashing - Average Search Time
#include <iostream>
using namespace std;
const int N = 10010;
int s, n, m;
int h[N];
bool is_prime(int x){
if (x == 1) return false;
for (int i = 2; i * i <= x; i ++ )
if (x % i == 0)
return false;
return true;
}
int find(int x, int &cnt){
int t = x % s;
cnt = 1;
for (int k = 0; k < s; k ++, cnt ++ ){
int i = (t + k * k) % s;
if (!h[i] || h[i] == x) return i;
}
return -1;
}
int main(){
cin >> s >> n >> m;
while (!is_prime(s)) s ++ ;
for (int i = 0; i < n; i ++ ){
int x, count;
cin >> x;
int t = find(x, count);
if (t == -1) printf("%d cannot be inserted.\n", x);
else h[t] = x;
}
int cnt = 0;
for (int i = 0; i < m; i ++ ){
int x, count;
cin >> x;
find(x, count);
cnt += count;
}
printf("%.1lf\n", (double)cnt / m);
return 0;
}
1137 Final Grading
#include <iostream>
#include <cstring>
#include <unordered_map>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
struct Student{
string id;
int p, m, f, s;
Student(): p(-1), m(-1), f(-1), s(0) {}
void calc(){
if (f >= m) s = f;
else s = round(m * 0.4 + f * 0.6);
}
bool operator< (const Student& t) const{
if (s != t.s) return s > t.s;
return id < t.id;
}
};
int main(){
int p, m, n;
cin >> p >> m >> n;
unordered_map<string, Student> hash;
string id;
int s;
for (int i = 0; i < p; i ++ ){
cin >> id >> s;
hash[id].id = id;
hash[id].p = s;
}
for (int i = 0; i < m; i ++ ){
cin >> id >> s;
hash[id].id = id;
hash[id].m = s;
}
for (int i = 0; i < n; i ++ ){
cin >> id >> s;
hash[id].id = id;
hash[id].f = s;
}
vector<Student> students;
for (auto item : hash){
auto stu = item.second;
stu.calc();
if (stu.p >= 200 && stu.s >= 60)
students.push_back(stu);
}
sort(students.begin(), students.end());
for (auto s : students)
cout << s.id << ' ' << s.p << ' ' << s.m << ' ' << s.f << ' ' << s.s << endl;
return 0;
}