All for PAT秋考 | 2019.3PAT甲级

半年过去了,昨天终于重新面对这套题目(是的,206块➕11块),竟然还是没做完,重现了考场上的崩溃。那个倒计时跟当时考试一模一样,真是emmm


59 分

今天冷静下来,再看,似乎不是题目本身难,是我细节没有抓好啊!!!


7-1 Sexy Primes (20 分)

素数对,写的还不如3月在考场上写的。可能读题没当时认真吧。
👇考场上的AC代码

#include <bits/stdc++.h>

using namespace std;

bool is_prime(int num) {
    if (num <= 1) return false;
    for (int i = 2; i * i <= num; i++) {
        if (num % i == 0)
            return false;
    }
    return true;
}

int main() {
    int nn;
    scanf("%d", &nn);
    if (is_prime(nn)) {
        if (nn > 6 && is_prime(nn - 6)) {
            printf("Yes\n%d\n", nn - 6);
            return 0;
        }
        if (is_prime(nn + 6)) {
            printf("Yes\n%d\n", nn + 6);
            return 0;
        }
    }
    printf("No\n");
    while (!is_prime(nn) || !(is_prime(nn + 6) || is_prime(nn - 6)))
        nn++;
    printf("%d\n", nn);
    return 0;
}

7-2 Anniversary (25 分)

查找➕排序,再次踏进同一个坑,导致了昨天的自闭。
写了一个结构体,存string id和int birth(从id中抽出来的生日),重载了小于号(小:出生较早的),忽略了一件重要的事情——⚠️这样就认为生日一样即为相等(同一人)了,即便再比较id也不行。set<结构体>就自带了顺序。然后就烂了呀……考场上错了1个5分的case……昨天第一遍写错的更多!就自闭了……
不要想太多,set<Person>给来宾按生日排个序,set<string>直接存校友id,挨个find()就完事儿了!

#include <cstdio>
#include <algorithm>
#include <set>
#include <string>
#include <cmath>
#include <iostream>

using namespace std;

struct Person {
    int birth;
    string id;

    bool operator<(const Person &p2) const {
        if (birth != p2.birth) return birth < p2.birth;
        return id < p2.id;
    }
} alu, com;

set<string> aluid;
set<Person> coms;

int main() {
    int nn, mm;
    cin >> nn;
    for (int i = 0; i < nn; ++i) {
        cin >> alu.id;
        int temp = 0;
        for (int j = 6; j < 14; ++j) {
            temp *= 10;
            temp += (alu.id[j] - '0');
        }
        alu.birth = temp;
        aluid.insert(alu.id);
    }
    int cnt = 0;
    cin >> mm;
    for (int i = 0; i < nn; ++i) {
        cin >> com.id;
        int temp = 0;
        for (int j = 6; j < 14; ++j) {
            temp *= 10;
            temp += (com.id[j] - '0');
        }
        com.birth = temp;
        if (aluid.find(com.id) != aluid.end()) {
            cnt++;
        }
        coms.insert(com);
    }
    cout << cnt << endl;
    if (cnt == 0) cout << coms.begin()->id << endl;
    else
        for (auto &item:coms) {
            if (aluid.find(item.id) != aluid.end()) {
                cout << item.id << endl;
                break;
            }
        }
    return 0;
}

7-3 Telefraud Detection

3月考场上一看,并查集啊,拿手!!结果错了一个6分的case…… 发现通常不是算法写错,而是把输入处理成算法开始时的数据的阶段出错了……题目描述已经这么多幺蛾子了!!!你就老老实实做呗!别给自己找事儿……(并查集——祖先标号大的和祖先标号小的合并,合并到小的,写法注意)

#include <cstdio>
#include <algorithm>
#include <set>
#include <map>

using namespace std;
int uf[1001];

int _find(int curr) {
    return uf[curr] < 0 ? curr : uf[curr] = _find(uf[curr]);
}

void _union(int a, int b) {
    a = _find(a);
    b = _find(b);
    if (a > b) {
        uf[b] += uf[a];
        uf[a] = b;
    } else if (a < b) {
        uf[a] += uf[b];
        uf[b] = a;
    }
}

int main() {
    int graph[1010][1010] = {0};
    bool isSuspect[1010] = {false};
    int KK, NN, MM;
    scanf("%d%d%d", &KK, &NN, &MM);
    for (int i = 0; i < MM; ++i) {
        int v1, v2, dur;
        scanf("%d%d%d", &v1, &v2, &dur);
        graph[v1][v2] += dur;
    }
    int call, call_back, cnt_suspect = 0;
    for (int i = 1; i <= NN; ++i) {
        call = call_back = 0;
        for (int j = 1; j <= NN; ++j) {
            if (graph[i][j] > 0 && graph[i][j] <= 5) {
                call++;
                if (graph[j][i] > 0)
                    call_back++;
            }
        }
        if (call > KK && call_back * 5 <= call) {
            isSuspect[i] = true;
            cnt_suspect++;
        }
    }
    if (cnt_suspect == 0) {
        printf("None\n");
        return 0;
    }
    fill(uf, uf + 1010, -1);
    for (int i = 1; i <= NN; ++i) {
        if (isSuspect[i]) {
            for (int j = 1; j <= NN; ++j) {
                if (isSuspect[j] && graph[i][j] && graph[j][i])
                    _union(i, j);
            }
        }
    }
    map<int, set<int>> res;
    for (int i = 1; i <= NN; ++i) {
        if (isSuspect[i]) {
            res[_find(i)].insert(i);
        }
    }
    for (auto &item:res) {
        int size = item.second.size();
        for (auto item1:item.second) {
            size--;
            printf("%d", item1);
            printf(size ? " " : "\n");
        }
    }
    return 0;
}

7-4 Structure of a Binary Tree

考场上写到这儿还有将近一个半小时 = = ,然而前面case还有大分没拿,看了看输入那么麻烦(当时没记住C++ string的几个重要函数,也不会用sscanf),竟然就这么放弃了……

  • 输入处理
    利用string的find函数查找子串(找不到返回-1),结合sscanf就非常简单了!
  • Node结构体中包括key,lchild,rchild,father,depth字段。由中序、后序序列递归建树时,就把这些字段都填上。然后就,so easy了。。。
  • ⚠️root->child->father要先判断child不是NULL, root->child->key之类也要判断是否可能是空指针!!!
#include <iostream>
#include <string>

using namespace std;
int post_seq[32], in_seq[32], nn, nq;
bool isFull = true;

struct Node {
    int key, depth;
    Node *father = NULL, *lchild = NULL, *rchild = NULL;
};

Node *createBTree(int post_st, int post_ed, int in_st, int in_ed, int depth) {
    if (post_st > post_ed || in_st > in_ed) {
        return NULL;
    }
    Node *root = new Node;
    int rkey = post_seq[post_ed], pos = -1;
    for (int i = in_st; i <= in_ed; ++i) {
        if (in_seq[i] == rkey) {
            pos = i;
            break;
        }
    }
    root->key = rkey;
    root->depth = depth;
    int lsize = pos - in_st;
    root->lchild = createBTree(post_st, post_st + lsize - 1, in_st, pos - 1, depth + 1);
    root->rchild = createBTree(post_st + lsize, post_ed - 1, pos + 1, in_ed, depth + 1);
    if (isFull && (root->lchild || root->rchild) && (!(root->lchild && root->rchild))) isFull = false;
    if (root->lchild) root->lchild->father = root;
    if (root->rchild) root->rchild->father = root;
    return root;
}

Node *searchKey(Node *root, int x) {
    if (root == NULL) return NULL;
    if (root->key == x)
        return root;
    Node *temp = searchKey(root->lchild, x);
    if (temp) return temp;
    return searchKey(root->rchild, x);
}

int main() {
    cin >> nn;
    for (int i = 0; i < nn; ++i) {
        cin >> post_seq[i];
    }
    for (int i = 0; i < nn; ++i) {
        cin >> in_seq[i];
    }
    Node *root = createBTree(0, nn - 1, 0, nn - 1, 1);
    cin >> nq;
    getchar(); // !!!!!!
    string str;
    bool res;
    int A, B;
    for (int i = 0; i < nq; ++i) {
        getline(cin, str);
        if (str.find("root") != -1) {
            sscanf(str.data(), "%d is the root", &A);
            res = (root->key == A);
        } else if (str.find("siblings") != -1) {
            sscanf(str.data(), "%d and %d are siblings", &A, &B);
            res = (searchKey(root, A)->father == searchKey(root, B)->father);
        } else if (str.find("parent") != -1) {
            sscanf(str.data(), "%d is the parent of %d", &A, &B);
            Node *pp = searchKey(root, A);
            int lk, rk;
            lk = (pp->lchild != NULL ? pp->lchild->key : -1);
            rk = (pp->rchild != NULL ? pp->rchild->key : -1);
            res = (lk == B || rk == B);
        } else if (str.find("child") != -1) {
            if (str.find("left") != -1) {
                sscanf(str.data(), "%d is the left child of %d", &A, &B);
                Node *pp = searchKey(root, B);
                if (pp->lchild == NULL) res = false;
                else res = (pp->lchild->key == A);
            } else {
                sscanf(str.data(), "%d is the right child of %d", &A, &B);
                Node *pp = searchKey(root, B);
                if (pp->rchild == NULL) res = false;
                else res = (pp->rchild->key == A);
            }
        } else if (str.find("level") != -1) {
            sscanf(str.data(), "%d and %d are on the same level", &A, &B);
            res = (searchKey(root, A)->depth == searchKey(root, B)->depth);
        } else if (str.find("full") != -1)
            res = isFull;
        puts(res ? "Yes" : "No");
    }
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353

推荐阅读更多精彩内容