PAT甲级刷题记录-(AcWing)-Day15(模拟 8题 并查集 1题)

PAT甲级刷题记录-(AcWing)-Day15(模拟 8题 并查集 1题)

课程来源AcWing
其中AcWing中的题目为翻译好的中文题目

1008 Elevator

AcWing链接
PAT链接

注意点

#include <iostream>
#include <cstring>

using namespace std;
int n;

int main() {
    
    
    cin >> n;
    int res = 0;
    int cur = 0;
    while (n--) {
    
    
        int x;
        cin >> x;
        if (cur < x)res += (x - cur) * 6;
        else res += (cur - x) * 4;
        res += 5;
        cur = x;
    }
    cout << res << endl;
    return 0;
}

1011 World Cup Betting

AcWing链接
PAT链接

英语单词

解析

注意点

#include <iostream>
#include <vector>

using namespace std;
double w, t, l;

int main() {
    
    
    double res = 1;
    for (int i = 0; i < 3; ++i) {
    
    
        cin >> w >> t >> l;
        double x = max(w, max(t, l));
        if (x == w) cout << "W ";
        else if (x == t) cout << "T ";
        else cout << "L ";
        res *= x;
    }
    printf("%.2lf\n", (res * 0.65 - 1) * 2);
    return 0;
}

1014 Waiting in Line

AcWing链接
PAT链接

解析
每个窗口用一个队列来维护
队列中存放的是每个人的服务完成时间
对于输入的所有人,依次插入队列

  • 如果输入的序号在 n*m 之前,则按队列编号顺序找到排队人数最少的那个插入, 并计算当前队列的总共结束时间(8.00 + 队列中所有人的服务时间)
  • 如果是要在黄线后面排队的人,则找到完成时间最早的那个队列(对头元素最小的)
    1. 将目标队列出队,然后插入当前要去排队的人,并更新队列的总结束时间, 将当前人的结束时间加入哈希表
    2. 这里要判断一下办理的人是否在5.00前申请办理
  • 最后根据哈希表查询每个人的完成时间即可

注意点

#include <iostream>
#include <queue>
#include <unordered_map>

using namespace std;
const int N = 30;
int n, m, k, q;
queue<int> windows[N]; // n个窗口
unordered_map<int, int> map; // 顾客编号从1到k
int sum[N]; //每个窗口的总服务时间
int main() {
    
    
    cin >> n >> m >> k >> q;
    for (int i = 1; i <= k; ++i) {
    
    
        int service;
        cin >> service;
        int target = 0;
        for (int j = 0; j < n; ++j) {
    
     //找需要插入的队列
            if (i <= n * m) {
    
    
                // 可以直接加入到队列中, 找排队人数最小的那个队列
                if (windows[j].size() < windows[target].size()) target = j;
            } else {
    
    
                // 要先在黄线后面排队, 找第一个结束服务的队列
                if (windows[j].front() < windows[target].front()) target = j;
            }
        }
        // 此时target为要插入的队列
        int cur_over = sum[target] + service; // 当前顾客的服务完成时间等于队列的总完成时间+自己要服务的时间
        windows[target].push(cur_over);
        sum[target] += service; // 更新队列的总结束时间
        if (i > n * m) windows[target].pop();
        if (sum[target] - service < 540) map[i] = sum[target];
    }
    while (q--) {
    
    
        int id;
        cin >> id;
        if (map.count(id)) printf("%02d:%02d\n", map[id] / 60 + 8, map[id] % 60);
        else puts("Sorry");
    }
    return 0;
}

1031 Hello World for U

AcWing链接
PAT链接

英语单词

解析
用不等式先算出来n1的最大取值, 然后按顺序划分输出即可

注意点

 if(res[i][j]) cout << res[i][j];
 else cout << " ";
#include <iostream>

const int N = 100;
using namespace std;
string s;
char res[N][N];

int main() {
    
    
    cin >> s;
    int n = s.size();
    int n1 = min((n + 2) / 3, (n - 1) / 2);
    int n2 = n + 2 - 2 * n1;
    int idx = 0;
    for (int i = 0; i < n1; ++i) {
    
    
        res[i][0] = s[idx++];
    }
    for (int i = 1; i < n2; ++i) {
    
    
        res[n1 - 1][i] = s[idx++];
    }
    for (int i = n1 - 2; i >= 0; i--) {
    
    
        res[i][n2 - 1] = s[idx++];
    }
    for (int i = 0; i < n1; ++i) {
    
    
        for (int j = 0; j < n2; ++j) {
    
    
            if(res[i][j]) cout << res[i][j];
            else cout << " ";
        }
        cout << endl;
    }
    return 0;
}

1041 Be Unique

AcWing链接
PAT链接

英语单词

  • lottery 彩票
  • bet on 就…打赌

解析

注意点

#include <iostream>
#include <vector>

const int N = 10010;
using namespace std;
vector<int> num;
int st[N];

int main() {
    
    
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
    
    
        int x;
        cin >> x;
        num.push_back(x);
        st[x]++;
    }
    bool has = false;
    for (auto &x:num) {
    
    
        if (st[x] == 1) {
    
    
            cout << x;
            has = true;
            break;
        }
    }
    if(!has) puts("None");
    return 0;
}

1042 Shuffling Machine

AcWing链接
PAT链接

注意点
void *memcpy(void *str1, const void *str2, size_t n)

  • 从存储区 str2 复制 n 个字节到存储区 str1。
#include <iostream>
#include <cstring>

using namespace std;
int card[60], res[60], order[60], k;

void print(int x) {
    
    
    if (x <= 13) cout << "S" << x;
    else if (x <= 26) cout << "H" << x - 13;
    else if (x <= 39) cout << "C" << x - 26;
    else if (x <= 4 * 13) cout << "D" << x - 39;
    else cout << "J" << x - 4 * 13;
}

int main() {
    
    
    cin >> k;
    for (int i = 1; i < 55; ++i) {
    
    
        card[i] = i;
    }
    for (int i = 1; i < 55; ++i) {
    
    
        cin >> order[i];
    }
    while (k--) {
    
    
        memcpy(res, card, sizeof(res)); // card = res
        for (int i = 1; i < 55; ++i) {
    
    
            card[order[i]] = res[i];
        }
    }
    print(card[1]);
    for (int i = 2; i < 55; ++i) {
    
    
        cout << " ";
        print(card[i]);
    }
    return 0;
}

1047 Student List for Course

AcWing链接
PAT链接

英语单词

解析
也可以用 vector<string> lessons[N]来存储

注意点
一开始有一个点超时了,然后把cin都改成scanf printf就对了

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

using namespace std;

unordered_map<int, vector<string>> map;
int n, k;

int main() {
    
    
    scanf("%d %d", &n, &k);
    while (n--) {
    
    
        char name[10];
        scanf("%s", name);
        int cnt;
        cin >> cnt;
        while (cnt--) {
    
    
            int course;
            scanf("%d", &course);
            map[course].push_back(name);
        }
    }
    for (int i = 1; i <= k; ++i) {
    
    
        auto stu_list = map[i];
        printf("%d %d\n", i, stu_list.size());
        sort(stu_list.begin(), stu_list.end());
        for (auto &item:stu_list) {
    
    
            printf("%s\n", item.c_str());
        }
    }
    return 0;
}

1054 The Dominant Color

AcWing链接
PAT链接

英语单词

  • the resolutions of the image 图像的分辨率

解析

注意点
vector<pair<int,int>>的排序先按第一个关键字的升序,再按第二个关键字的升序, 所以这里我们要得到降序, 在插入的时候加个负号就好了

这种方法有点麻烦,还是后面一种好

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

using namespace std;
unordered_map<int, int> map;
vector<pair<int, int>> colors;
int m, n;

int main() {
    
    
    cin >> m >> n;
    while (n--) {
    
    
        for (int i = 0; i < m; ++i) {
    
    
            int c;
            cin >> c;
            map[c]++;
        }
    }
    for (auto &item:map) {
    
    
        colors.push_back({
    
    -item.second, item.first,});
    }
    sort(colors.begin(), colors.end());
    cout << colors[0].second << endl;
    return 0;
}

一种简单的写法, 在输入过程中看看当前颜色有没有超过一半的像素数量即可

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

using namespace std;
unordered_map<int, int> map;
int m, n;

int main() {
    
    
    cin >> m >> n;
    for (int i = 0; i < n * m; ++i) {
    
    
        int x;
        cin >> x;
        if (++map[x] > n * m / 2) {
    
    
            cout << x;
            break;
        }
    }
    return 0;
}

1107 Social Clusters

AcWing链接
PAT链接

注意点
注意从序号从1开始的一些问题

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

const int N = 1010;
using namespace std;
int n;
vector<int> hobby[N];
int p[N];
int cnt[N];

int find(int x) {
    
    
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}

int main() {
    
    
    cin >> n;
    for (int i = 1; i < n + 1; ++i) {
    
    
        int k;
        scanf("%d: ", &k);
        while (k--) {
    
    
            int id;
            cin >> id;
            hobby[id].push_back(i);
        }
    }
    // 初始化并查集
    for (int i = 1; i < n + 1; ++i) {
    
    
        p[i] = i;
    }
    // 合并并查集
    for (int i = 1; i < N; ++i) {
    
    
        if (hobby[i].size() > 0) {
    
    
            int a = hobby[i][0];
            for (int j = 1; j < hobby[i].size(); ++j) {
    
    
                int b = hobby[i][j];
                // 把所有的b都合并到a里面去
                p[find(a)] = find(b);
            }
        }
    }
    // 统计相同祖先的集合数量
    for (int i = 1; i < n + 1; ++i) {
    
    
        cnt[find(i)]++;
    }
    sort(cnt + 1, cnt + n + 1, greater<int>()); // 从大到小排序
    int k = 1;
    // 找前k个不为0的值,记录集群的数量
    while (cnt[k]) k++;
    cout << k << endl;
    cout << cnt[1];
    for (int i = 2; i < k; ++i) {
    
    
        cout << " " << cnt[i];
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Weary_PJ/article/details/125074636
今日推荐