PAT-数据结构与基础算法(AcWingPAT甲级课笔记)

目录

链表

1032 Sharing

1074 Reversing Linked List

1097 Deduplication on a Linked List

1133 Splitting A Linked List

二路归并

1029 Median

前缀和

1046 Shortest Distance

双指针

1085 Perfect Sequence

1044 Shopping in Mars

BFS

1091 Acute Stroke

枚举

1148 Werewolf - Simple Version

1117 Eddington Number

1040 Longest Symmetric String

1051 Pop Sequence

1055 The World's Richest

1057 Stack


链表

暴力:

先把链表里的数据放入数组,按题目要求对数组进行操作,最后再把数组转化成链表输出

1032 Sharing

解析

1.先建立链表,把输入的数据存下里啊

2.先遍历第一个链表,把链表里的地址都存入到哈希表中

3.再遍历第二个链表,找到一个元素在哈希表中存在过,该地址就是要求的地址

#include <iostream>
#include <cstring>

using namespace std;

const int N = 100010;

int n;
int h1, h2, ne[N];
char e[N];
bool st[N];

int main(){
    scanf("%d%d%d", &h1, &h2, &n);
    for (int i = 0; i < n; i ++ ){
        int address, next;
        char data;
        scanf("%d %c %d", &address, &data, &next);
        e[address] = data, ne[address] = next;
    }

    for (int i = h1; i != -1; i = ne[i])
        st[i] = true;

    for (int i = h2; i != -1; i = ne[i])
        if (st[i]){
            printf("%05d\n", i);
            return 0;
        }

    puts("-1");

    return 0;
}

1074 Reversing Linked List

解析:

1.先把链表存下来,放入vector里

2.对vector做翻转

3.把vector再转成链表

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 100010;

int n, m;
int h, e[N], ne[N];

int main(){
    scanf("%d%d%d", &h, &n, &m);

    for (int i = 0; i < n; i ++ ){
        int address, data, next;
        scanf("%d%d%d", &address, &data, &next);
        e[address] = data, ne[address] = next;
    }

    vector<int> q;
    for (int i = h; i != -1; i = ne[i]) q.push_back(i);

    for (int i = 0; i + m - 1 < q.size(); i += m)
        reverse(q.begin() + i, q.begin() + i + m);

    for (int i = 0; i < q.size(); i ++ ){
        printf("%05d %d ", q[i], e[q[i]]);
        if (i + 1 == q.size()) puts("-1");
        else printf("%05d\n", q[i + 1]);
    }

    return 0;
}

1097 Deduplication on a Linked List

#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

const int N = 100010;

int n;
int h, e[N], ne[N];
bool st[N];

int main(){
    scanf("%d%d", &h, &n);
    for (int i = 0; i < n; i ++ ){
        int address, key, next;
        scanf("%d%d%d", &address, &key, &next);
        e[address] = key, ne[address] = next;
    }

    vector<int> a, b;
    for (int i = h; i != -1; i = ne[i]){
        int v = abs(e[i]);
        if (st[v]) b.push_back(i);
        else{
            st[v] = true;
            a.push_back(i);
        }
    }

    for (int i = 0; i < a.size(); i ++ ){
        printf("%05d %d ", a[i], e[a[i]]);
        if (i + 1 == a.size()) puts("-1");
        else printf("%05d\n", a[i + 1]);
    }
    for (int i = 0; i < b.size(); i ++ ){
        printf("%05d %d ", b[i], e[b[i]]);
        if (i + 1 == b.size()) puts("-1");
        else printf("%05d\n", b[i + 1]);
    }

    return 0;
}

1133 Splitting A Linked List

#include <iostream>
#include <cstring>
#include <vector>

using namespace std;

const int N = 100010;

int n, k;
int h, e[N], ne[N];

int main(){
    scanf("%d%d%d", &h, &n, &k);
    for (int i = 0; i < n; i ++ ){
        int address, key, next;
        scanf("%d%d%d", &address, &key, &next);
        e[address] = key, ne[address] = next;
    }

    vector<int> a, b, c;
    for (int i = h; i != -1; i = ne[i]){
        int v = e[i];
        if (v < 0) a.push_back(i);
        else if (v <= k) b.push_back(i);
        else c.push_back(i);
    }

    a.insert(a.end(), b.begin(), b.end());
    a.insert(a.end(), c.begin(), c.end());

    for (int i = 0; i < a.size(); i ++ ){
        printf("%05d %d ", a[i], e[a[i]]);
        if (i + 1 == a.size()) puts("-1");
        else printf("%05d\n", a[i + 1]);
    }

    return 0;
}

二路归并

1029 Median

#include <iostream>
#include <cstring>

using namespace std;

const int N = 200010;

int n, m;
int a[N], b[N], c[N * 2];

int main(){
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
    scanf("%d", &m);
    for (int i = 0; i < m; i ++ ) scanf("%d", &b[i]);

    int k = 0, i = 0, j = 0;
    while (i < n && j < m)
        if (a[i] <= b[j]) c[k ++ ] = a[i ++ ];
        else c[k ++ ] = b[j ++ ];
    while (i < n) c[k ++ ] = a[i ++ ];
    while (j < m) c[k ++ ] = b[j ++ ];

    printf("%d\n", c[(n + m - 1) / 2]);

    return 0;
}

前缀和

1046 Shortest Distance

#include <iostream>
#include <cstring>

using namespace std;

const int N = 100010;

int n, m;
int s[N];

int main(){
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ){
        scanf("%d", &s[i]);
        s[i] += s[i - 1];
    }

    scanf("%d", &m);
    while (m -- ){
        int l, r;
        scanf("%d%d", &l, &r);
        if (l > r) swap(l, r);
        printf("%d\n", min(s[r - 1] - s[l - 1], s[n] - s[r - 1] + s[l - 1]));
    }

    return 0;
}

双指针

1085 Perfect Sequence

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int n, p;
int a[N];

int main(){
    scanf("%d%d", &n, &p);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);

    sort(a, a + n);

    int res = 0;
    for (int i = 0, j = 0; i < n; i ++ ){
        while ((long long)a[j] * p < a[i]) j ++ ;
        res = max(res, i - j + 1);
    }

    printf("%d\n", res);
    return 0;
}


1044 Shopping in Mars

#include <iostream>
#include <cstring>

using namespace std;

const int N = 100010, INF = 1e9;

int n, m;
int s[N];

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ )
    {
        scanf("%d", &s[i]);
        s[i] += s[i - 1];
    }

    int res = INF;
    for (int i = 1, j = 0; i <= n; i ++ )
    {
        while (s[i] - s[j + 1] >= m) j ++ ;
        if (s[i] - s[j] >= m) res = min(res, s[i] - s[j]);
    }

    for (int i = 1, j = 0; i <= n; i ++ )
    {
        while (s[i] - s[j + 1] >= m) j ++ ;
        if (s[i] - s[j] == res) printf("%d-%d\n", j + 1, i);
    }

    return 0;
}

BFS

1091 Acute Stroke

#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

const int M = 1286, N = 128, L = 60;

int m, n, l, T;
int g[L][M][N];
struct Node
{
    int x, y, z;
};

int d[][3] = {
    {1, 0, 0},
    {-1, 0, 0},
    {0, 1, 0},
    {0, -1, 0},
    {0, 0, 1},
    {0, 0, -1},
};

int bfs(int x, int y, int z)
{
    queue<Node> q;
    q.push({x, y, z});
    g[x][y][z] = 0;

    int cnt = 1;
    while (q.size())
    {
        auto t = q.front();
        q.pop();

        for (int i = 0; i < 6; i ++ )
        {
            int a = t.x + d[i][0], b = t.y + d[i][1], c = t.z + d[i][2];
            if (a >= 0 && a < l && b >= 0 && b < m && c >= 0 && c < n && g[a][b][c])
            {
                g[a][b][c] = 0;
                q.push({a, b, c});
                cnt ++ ;
            }
        }
    }

    return cnt;
}

int main()
{
    scanf("%d%d%d%d", &m, &n, &l, &T);

    for (int i = 0; i < l; i ++ )
        for (int j = 0; j < m; j ++ )
            for (int k = 0; k < n; k ++ )
                scanf("%d", &g[i][j][k]);

    int res = 0;
    for (int i = 0; i < l; i ++ )
        for (int j = 0; j < m; j ++ )
            for (int k = 0; k < n; k ++ )
                if (g[i][j][k])
                {
                    int t = bfs(i, j, k);
                    if (t >= T) res += t;
                }

    printf("%d\n", res);

    return 0;
}

枚举


1148 Werewolf - Simple Version

#include <iostream>
#include <cstring>

using namespace std;

const int N = 110;

int n;
int q[N];

int judge(int k, int i, int j)  // 如果是假话,返回1;如果是真话,返回0
{
    int t = q[k];
    if (t > 0)
    {
        if (t == i || t == j) return 1;
        return 0;
    }

    t = -t;
    if (t == i || t == j) return 0;
    return 1;
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ ) cin >> q[i];

    for (int i = 1; i <= n; i ++ )
        for (int j = i + 1; j <= n; j ++ )
        {
            int s = judge(i, i, j) + judge(j, i, j);
            if (s != 1) continue;

            s = 0;
            for (int k = 1; k <= n; k ++ )
                s += judge(k, i, j);

            if (s != 2) continue;

            cout << i << ' ' << j << endl;
            return 0;
        }

    puts("No Solution");

    return 0;
}

1117 Eddington Number

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
int a[N];

int main()
{
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
    sort(a, a + n);

    for (int i = n; i; i -- )
        if (a[n - i] > i)
        {
            printf("%d\n", i);
            return 0;
        }

    puts("0");
    return 0;
}

1040 Longest Symmetric String

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    string str;
    getline(cin, str);

    int res = 0;
    for (int i = 0; i < str.size(); i ++ )
    {
        int l = i - 1, r = i + 1;
        while (l >= 0 && r < str.size() && str[l] == str[r]) l --, r ++ ;
        res = max(res, r - l - 1);

        l = i, r = i + 1;
        while (l >= 0 && r < str.size() && str[l] == str[r]) l --, r ++ ;
        res = max(res, r - l - 1);
    }

    cout << res << endl;

    return 0;
}

1051 Pop Sequence

#include <iostream>
#include <cstring>
#include <stack>

using namespace std;

const int N = 1010;

int m, n, k;
int a[N];

bool check()
{
    stack<int> stk;
    for (int i = 1, j = 0; i <= n; i ++ )
    {
        stk.push(i);
        if (stk.size() > m) return false;

        while (stk.size() && stk.top() == a[j])
        {
            stk.pop();
            j ++ ;
        }
    }

    return stk.empty();
}

int main()
{
    scanf("%d%d%d", &m, &n, &k);
    while (k -- )
    {
        for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
        if (check()) puts("YES");
        else puts("NO");
    }

    return 0;
}

1055 The World's Richest

#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

const int N = 210;

int n, m;
struct Person
{
    string name;
    int age, w;

    bool operator< (const Person& t) const
    {
        if (w != t.w) return w > t.w;
        if (age != t.age) return age < t.age;
        return name < t.name;
    }
};

vector<Person> ages[N];
int idx[N];

int main()
{
    scanf("%d%d", &n, &m);

    char name[10];
    for (int i = 0; i < n; i ++ )
    {
        int age, w;
        scanf("%s%d%d", name, &age, &w);
        ages[age].push_back({name, age, w});
    }

    for (auto& age : ages) sort(age.begin(), age.end());

    for (int C = 1; C <= m; C ++ )
    {
        printf("Case #%d:\n", C);
        int cnt, a, b;
        scanf("%d%d%d", &cnt, &a, &b);

        memset(idx, 0, sizeof idx);
        bool exists = false;
        while (cnt -- )
        {
            int t = -1;
            for (int i = a; i <= b; i ++ )
                if (idx[i] < ages[i].size())
                {
                    if (t == -1 || ages[i][idx[i]] < ages[t][idx[t]])
                        t = i;
                }

            if (t == -1) break;
            auto& p = ages[t][idx[t]];
            idx[t] ++ ;

            printf("%s %d %d\n", p.name.c_str(), p.age, p.w);
            exists = true;
        }

        if (!exists) puts("None");
    }

    return 0;
}

1057 Stack

#include <iostream>
#include <cstring>
#include <set>
#include <stack>

using namespace std;

stack<int> stk;
multiset<int> up, down;

void adjust()
{
    while (up.size() > down.size())
    {
        down.insert(*up.begin());
        up.erase(up.begin());
    }

    while (down.size() > up.size() + 1)
    {
        auto it = down.end();
        it -- ;
        up.insert(*it);
        down.erase(it);
    }
}

int main()
{
    int n;
    scanf("%d", &n);
    char op[20];
    while (n -- )
    {
        scanf("%s", op);
        if (strcmp(op, "Push") == 0)
        {
            int x;
            scanf("%d", &x);
            stk.push(x);
            if (up.empty() || x < *up.begin()) down.insert(x);
            else up.insert(x);
            adjust();
        }
        else if (strcmp(op, "Pop") == 0)
        {
            if (stk.empty()) puts("Invalid");
            else
            {
                int x = stk.top();
                stk.pop();
                printf("%d\n", x);
                auto it = down.end();
                it -- ;
                if (x <= *it) down.erase(down.find(x));
                else up.erase(up.find(x));

                adjust();
            }
        }
        else
        {
            if (stk.empty()) puts("Invalid");
            else
            {
                auto it = down.end();
                it -- ;
                printf("%d\n", *it);
            }
        }
    }

    return 0;
}

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值