PAT グレード A 質問記録-(AcWing)-Day10(DP 1 質問ハッシュ テーブル 8 質問)

PAT グレード A 質問記録-(AcWing)-Day10(DP 1 質問ハッシュ テーブル 8 質問)

このコースは AcWing から提供されており、
AcWing のタイトルは中国語のタイトルに翻訳されています。

1007 最大サブシーケンス合計

AcWリンク
PATリンク

DPの考え方に注意してください
、しかしクラスAはこのテストを受けないようです、今のところは放っておいてください

#include<iostream>

using namespace std;
const int N = 10010;
int w[N], k;

int main() {
    
    
    cin >> k;
    for (int i = 1; i <= k; i++) cin >> w[i];
    int res = -1, l = 0, r = 0;
    for (int i = 1, f = 0, start = i; i <= k; i++) {
    
    
        if (f < 0) f = 0, start = i;
        f += w[i];
        if (res < f) {
    
    
            l = w[start];
            r = w[i];
            res = f;
        }
    }
    if (res < 0) res = 0, l = w[1], r = w[k];
    cout << res << " " << l << " " << r << endl;
    return 0;
}

1048 コインを探す

AcWリンク
PATリンク

英単語

分析する

注意点

#include <iostream>
#include <unordered_set>
#include <climits>

using namespace std;
unordered_set<int> set;
int w[100010], n, m;;

bool check(int target) {
    
    
    int con;
    for (int i = 0; i < n; ++i) {
    
    
        if (w[i] == target) con++;
    }
    if (con >= 2) return true;
    return false;
}

int main() {
    
    

    cin >> n >> m;
    for (int i = 0; i < n; ++i) {
    
    
        int x;
        cin >> x;
        w[i] = x;
        set.insert(x);
    }
    // 找 v1 + v2 = m
    int v1 = INT_MAX, v2;
    for (int i = 0; i < n; ++i) {
    
    
        int target = m - w[i];
        if (target == w[i]) {
    
    
            if (check(target)) {
    
    
                if (v1 > min(target, w[i])) v1 = min(target, w[i]), v2 = max(target, w[i]);
            }
        } else {
    
    
            if (set.count(target)) {
    
    
                if (v1 > min(target, w[i])) v1 = min(target, w[i]), v2 = max(target, w[i]);
            }
        }
    }
    if (v1 == INT_MAX) puts("No Solution");
    else cout << v1 << " " << v2 << endl;

    return 0;
}

方法2、入力途中に他の数字があるかどうかを判断する

#include <iostream>
#include <unordered_set>
#include <climits>

using namespace std;
unordered_set<int> set;
int w[100010], n, m;;

bool check(int target) {
    
    
    int con;
    for (int i = 0; i < n; ++i) {
    
    
        if (w[i] == target) con++;
    }
    if (con >= 2) return true;
    return false;
}

int main() {
    
    

    cin >> n >> m;
    // 找 v1 + v2 = m
    int v1 = INT_MAX, v2;
    for (int i = 0; i < n; ++i) {
    
    
        int x;
        cin >> x;
        int y = m - x;
        if (set.count(y)) {
    
    
            if (x > y) swap(x, y);
            if (x < v1) v1 = x, v2 = y;
        }
        set.insert(x);
    }
    if (v1 == INT_MAX) puts("No Solution");
    else cout << v1 << " " << v2 << endl;

    return 0;
}

1063 類似性を設定する

AcWリンク
PATリンク

; を
使用してトラバースできることに注意してください。for(int x:s)set

#include <iostream>
#include <unordered_set>

using namespace std;
unordered_set<int> S[60];

void func(int a, int b) {
    
    
    // 计算集合a和b的系数
    unordered_set<int> S1 = S[a];
    unordered_set<int> S2 = S[b];
    int nc = 0;
    for (auto x:S1) {
    
    
        nc += S2.count(x);
    }
    int nt = S1.size() + S2.size() - nc;
    printf("%.1lf%%\n", nc * 1.0 / nt * 100);

}

int main() {
    
    
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
    
    
        int m;
        cin >> m;
        while (m--) {
    
    
            int x;
            cin >> x;
            S[i].insert(x);
        }
    }
    int k;
    cin >> k;
    while (k--) {
    
    
        int a, b;
        cin >> a >> b;
        func(a, b);
    }
    return 0;
}

1120 友達番号

AcWリンク
PATリンク

英単語

分析する


setソートと重複排除の効果による注目ポイント

#include <iostream>
#include <set>

using namespace std;
int n;
set<int> s;

int main() {
    
    
    cin >> n;
    for (int i = 0; i < n; ++i) {
    
    
        string number;
        cin >> number;
        int sum = 0;
        for (auto &c:number) {
    
    
            sum += c - '0';
        }
        s.insert(sum);
    }
    cout << s.size() << endl;
    bool is_first = true;
    for (auto x:s) {
    
    
        if (is_first) is_first = false;
        else cout << " ";
        cout << x;
    }
    return 0;
}

1144 消えた数字

AcWリンク
PATリンク

英単語

分析する


サイクル中に上限が十分に大きくなかったため、エラーが 2 回報告されたことに注意してくださいINT_MAX。後で正しくなりました。

whileここでも使用できます

#include <iostream>
#include <unordered_set>
#include <climits>
using namespace std;
int n;
unordered_set<int> set;

int main() {
    
    
    cin >> n;
    for (int i = 0; i < n; ++i) {
    
    
        int x;
        cin >> x;
        set.insert(x);
    }
    for (int i = 1; i < INT_MAX; ++i) {
    
    
        if (!set.count(i)) {
    
    
            cout << i << endl;
            break;
        }
    }
    return 0;
}

1149 危険物の包装業

AcWリンク
PATリンク

#include <iostream>
#include <unordered_set>

using namespace std;
int n, m, k;
struct danger {
    
    
    int a, b;
} danger[10010];

int main() {
    
    
    cin >> n >> m;
    for (int i = 0; i < n; ++i)cin >> danger[i].a >> danger[i].b;
    while (m--) {
    
    
        cin >> k;
        unordered_set<int> set;
        while (k--) {
    
    
            int x;
            cin >> x;
            set.insert(x);
        }
        bool res = true;
        for (int i = 0; i < n; ++i) {
    
    
            if (set.count(danger[i].a) && set.count(danger[i].b)) {
    
    
                res = false;
                break;
            }
        }
        if (res) puts("Yes");
        else puts("No");
    }

    return 0;
}

1078 ハッシュ

AcWリンク
PATリンク

英単語

  • 二次関数プローブ (正の増分のみ) を使用して衝突を解決します。 二次関数プローブ (正の増分のみ) を使用して衝突を解決します。

注意点

  • 素数判定の際はx=1ifの状況に注意して直接返すfalse
  • iスクエアプローブを使用して補間する場合、size(table)-1
#include <iostream>

using namespace std;
int m_size, m;

bool is_prime(int x) {
    
    
    if (x == 1) return false;
    for (int i = 2; i <= x / i; ++i) {
    
    
        if (x % i == 0) return false;
    }
    return true;
};
bool visit[10010];

int find(int x) {
    
    
    int pos = x % m_size;
    if (!visit[pos]) return pos;
    for (int i = 0; i < m_size; ++i) {
    
    
        int t = (pos + i * i) % m_size;
        if (!visit[t]) return t;
    }
    return -1;
}

int main() {
    
    
    cin >> m_size >> m;
    while (!is_prime(m_size)) m_size++;
    bool is_first = true;
    for (int i = 0; i < m; ++i) {
    
    
        int x;
        cin >> x;
        int pos = find(x);
        if (is_first) is_first = false;
        else cout << " ";
        if (pos == -1) cout << "-";
        else cout << pos, visit[pos] = true;
    }

    return 0;
}

1145 ハッシュ - 平均検索時間

AcWリンク
PATリンク

英単語

分析する


平均検索時間を検索数で割った値であることに注意してください。

#include <iostream>

const int N = 10010;
using namespace std;
int s, n, m;
int h[N];
int count;

bool prime(int x) {
    
    
    if (x == 1) return false;
    for (int i = 2; i <= x / i; ++i) {
    
    
        if (x % i == 0) return false;
    }
    return true;
}

int find(int x, int &cnt) {
    
    
    int pos = x % s;
    cnt = 1;
    if (!h[pos] || h[pos] == x) return pos;
    for (int i = 1; i < s; ++i) {
    
    
        cnt++;
        int t = (pos + i * i) % s;
        if (!h[t] || h[t] == x)return t;
    }
    return -1;
}

int main() {
    
    
    cin >> s >> n >> m;
    while (!prime(s)) s++;
    while (n--) {
    
    
        int x, cnt;
        cin >> x;
        int pos = find(x, cnt);
        if (pos == -1) printf("%d cannot be inserted.\n", x);
        else h[pos] = x;
    }
    count = 0;
    int length = m;
    while (m--) {
    
    
        int x, cnt;
        cin >> x;
        int pos = find(x, cnt);
        if (pos == -1) count += s + 1;
        else count += cnt;
    }

    printf("%.1lf", count * 1.0 / length);
    return 0;
}

1137 最終グレーディング

AcWリンク
PATリンク

#include <iostream>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

struct Student {
    
    
    string id;
    int p, mid, final, total;

    Student() : p(-1), mid(-1), final(-1), total(0) {
    
    };

    void cal() {
    
    
        if (final >= mid) total = final;
        else total = round(mid * 0.4 + final * 0.6);
    }

    bool operator<(const Student &s) {
    
    
        if (total != s.total) return total > s.total;
        return id < s.id;
    }
};

unordered_map<string, Student> map;
vector<Student> res;

int main() {
    
    
    int p, m, n;
    string id;
    int score;
    cin >> p >> m >> n;
    while (p--) {
    
    
        cin >> id >> score;
        map[id].id = id; // 如果map中没有id,会根据构造函数创建一个Student对象
        map[id].p = score;
    }
    while (m--) {
    
    
        cin >> id >> score;
        map[id].id = id; // 如果map中没有id,会根据构造函数创建一个Student对象
        map[id].mid = score;
    }
    while (n--) {
    
    
        cin >> id >> score;
        map[id].id = id; // 如果map中没有id,会根据构造函数创建一个Student对象
        map[id].final = score;
    }
    for (auto &item:map) {
    
    
        auto stu = item.second;
        stu.cal();
        if (stu.total >= 60 && stu.p >= 200) res.push_back(stu);
    }
    sort(res.begin(), res.end());
    for (int i = 0; i < res.size(); ++i) {
    
    
        auto stu = res[i];
        cout << stu.id << " " << stu.p << " " << stu.mid << " " <<
             stu.final << " " << stu.total << endl;
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/Weary_PJ/article/details/125011611