PAT甲级题目

先把会做的做了,emmmm

1006


水题,关键就是在于如何切分字符串而已,考的应该也就是字符串了:


class sepration {
public:
    int hour = -1;
    int min = -1;
    int second = -1;

    sepration() {}

    sepration(int hour, int min, int second) {
        this->hour = hour;
        this->min = min;
        this->second = second;
    }
};

sepration getSepration(string time) {
    int sum = 0;
    sepration s;
    for (int i = 0; i < time.size(); ++i) {
        if (time[i] != ':') {
            sum = sum * 10 + (time[i] - '0');
        } else {
            if (s.hour == -1) {
                s.hour = sum;
            } else if (s.min == -1) {
                s.min = sum;
            }
            sum = 0;
        }
    }
    s.second = sum;
    return s;
}

1007


这个题目大名鼎鼎,一看就知道是动态规划,然鹅我不懂动态规划,用分治法做了,结果不过。牛客网看了一下,直接给了个9万多的数据,这样递归不爆炸才怪,先留着,学了动态规划再做了。

int getMax(int *array, int l, int r, int &left, int &right) {
    if (l == r) {
        left = right = array[l];
        return array[l];
    }
    int mid = (l + r) / 2;
    int maxLeft = INT_MIN;
    int maxLeftIndex = -1;
    int tempLeft = 0;
    for (int i = mid; i >= l; --i) {
        tempLeft += array[i];
        if (tempLeft > maxLeft) {
            maxLeftIndex = i;
            maxLeft = tempLeft;
        }
    }


    int maxRight = INT_MIN;
    int maxRightIndex = -1;
    int tempRight = 0;
    for (int i = mid + 1; i <= r; ++i) {
        tempRight += array[i];
        if (tempRight > maxRight) {
            maxRightIndex = i;
            maxRight = tempRight;
        }
    }


    int Lleft, Lright;
    int Rleft, Rright;

    int midSum = maxLeft + maxRight;
    int maxLeftSum = getMax(array, l, mid, Lleft, Lright);
    int maxRightSum = getMax(array, mid + 1, r, Rleft, Rright);


    int max = midSum;
    left = array[maxLeftIndex], right = array[maxRightIndex];


    if (max <= maxLeftSum) {
        max = maxLeftSum;
        left = array[Lleft];
        right = array[Lright];
    }
    if (max < maxRightSum) {
        max = maxRightSum;
        left = array[Rleft];
        right = array[Rright];
    }


    return max;

}

分治法思路也很简单,最大子串不是在左边就是在右边或者是跨越两边,分三个情况递归讨论即可。

1008


这个题目感觉有点小问题,特么的如果两层相同的话不应该只算等5秒吗?比如3 3,两个都是3层,那等5秒不就好了,然而去掉这个限制就过了。

//
// Created by GreenArrow on 2020/3/30.
//
#include <iostream>
#include <vector>

using namespace std;

vector<int> seperator(string s) {
    int sum = 0;
    vector<int> arr;
    for (int i = 0; i < s.size(); ++i) {
        if (s[i] != ' ')
            sum = sum * 10 + (s[i] - '0');
        else {
            arr.push_back(sum);
            sum = 0;
        }
    }
    arr.push_back(sum);
    return arr;
}

int main() {
    int n;
    vector<int> array;
    cin >> n;
    for (int j = 0; j < n; ++j) {
        int num;
        cin >> num;
        array.push_back(num);
    }
    int time = 0;
    int pre = 0;
    for (int i = 0; i < array.size(); ++i) {
        int cur = array[i];
        if (cur - pre > 0) {
            time += (cur - pre) * 6;
        } else if (cur - pre < 0) {
            time += (pre - cur) * 4;
        }

        time += 5;
        pre = cur;
    }
    cout << time;
}

1048


这个题目很明显就是索引,关键就是看你怎么存这个数字了,数据存储方式选的好,就简单。用一个数组存储次数即可。


int main() {
    int visited[MAX];
    fill(visited, visited + MAX, 0);
    int n, total;
    cin >> n >> total;
    for (int i = 0; i < n; ++i) {
        int num;
        cin >> num;
        visited[num]++;
    }

    int v1 = -1, v2 = -1;

    for (int j = 0; j < MAX; ++j) {
        if (visited[j]) {
            visited[j]--;
            if (total > j && visited[total - j]) {
                cout << j << " " << total - j;
                return 0;
            }
        }
    }

    cout << "No Solution";

}

1011


这个题目就比较水了,就是比较大小套公式就好了:

//
// Created by GreenArrow on 2020/4/1.
//
#include <iostream>

#define MAX 3
using namespace std;

int main() {
    double arr[MAX][MAX];
    int index_[MAX] = {-1};
    for (int i = 0; i < MAX; ++i) {
        double max = -1;
        for (int j = 0; j < MAX; ++j) {
            cin >> arr[i][j];
            if (max < arr[i][j]) {
                index_[i] = j;
                max = arr[i][j];
            }
        }
    }

    string a, b, c;
    double sum = 1;

    for (int k = 0; k < MAX; ++k) {
        if (index_[k] == 0) {
            cout << "W";
        } else if (index_[k] == 1) {
            cout << "T";
        } else if (index_[k] == 2) {
            cout << "L";
        }
        cout << " ";

        sum *= arr[k][index_[k]];

    }

    sum = (sum * 0.65 - 1) * 2;

    printf("%.2lf", sum);


}

1012


这个题目很简单,就是排序,但是有点小坑。和正常思维不一样,比如如果有并列,应该是1,1,2,3,4这样,但是这里是1,1,3,4,5,相同的也要算进去,测试点2就是这个情况,稍微处理一下即可。算法写的很麻烦,就是分开几个排序即可。

typedef struct student {
    string id;
    int A;
    int rankA;
    int C;
    int rankC;
    int M;
    int rankM;
    int E;
    int rankE;
    int origin;

    student(string id, int C, int M, int E) {
        this->id = id;
        this->C = C;
        this->M = M;
        this->E = E;
        this->A = (C + M + E) / 3;
    }
};

用一个结构体存储学生所有信息,包括原先排名,因为还准备了一个map存储数据索引。

    sort(students.begin(), students.end(), cmpA);
    setRankA(students);

    sort(students.begin(), students.end(), cmpC);
    setRankC(students);

    sort(students.begin(), students.end(), cmpM);
    setRankM(students);

    sort(students.begin(), students.end(), cmpE);
    setRankE(students);

    sort(students.begin(), students.end(), cmp);

分别排序之后进行排名赋值:

void setRankE(vector<student> &students) {
    int rank = 1;
    if (students.size() == 0)
        return;
    students[0].rankE = rank;
    for (int i = 1; i < students.size(); ++i) {
        if (students[i].E == students[i - 1].E) {
            students[i].rankE = students[i - 1].rankE;
            rank++;
        } else {
            students[i].rankE = ++rank;
        }
    }
}

赋值操作也很简单,注意特殊情况即可。

1015


这个题目就很明显是水题了,问你把相应进制的数字颠倒过来看看是不是还是一个素数。首先判断没变化前的数字是不是素数,然后判断变化之后是不是素数即可。

vector<int> getReverse(int number, int radix) {
    vector<int> results;
    while (number >= radix) {
        results.push_back(number % radix);
        number /= radix;
    }

    results.push_back(number);
    return results;
}

把数字变成进制的形式,不用翻转了,比如23的二进制,按照23%2进result,23/=2的形式,result里面就已经是翻转过来的了。

int radix2number(vector<int> result, int radix) {

    int sum = 0;
    for (int i = 0; i < result.size(); ++i) {
        sum = sum * radix + result[i];
    }

    return sum;

}

把result里面的进制转换成十进制。

int main() {
    int number, radix;
    cin >> number;
    while (number > 0) {
        cin >> radix;

        if (isPrime(number)) {

            int reversNumber = radix2number(getReverse(number, radix), radix);
            if (isPrime(reversNumber)) {
                cout << "Yes" << endl;
            } else
                cout << "No" << endl;

        } else {
            cout << "No" << endl;
        }
        cin >> number;
    }
    return 0;
}

主运行程序。

1019


这个题目很明显,水题,就是进制转换然后看看是不是回文串即可。

//
// Created by GreenArrow on 2020/4/6.
//
#include <iostream>
#include <vector>

using namespace std;

vector<int> getNumber(int number, int radix) {
    vector<int> sequences;
    while (number >= radix) {
        sequences.push_back(number % radix);
        number /= radix;
    }
    sequences.push_back(number);
    return sequences;
}

bool isPalindromic(vector<int> sequences) {
    for (int i = 0, j = sequences.size() - 1; i < j; ++i, j--) {
        if (sequences[i] != sequences[j]) {
            return false;
        }
    }
    return true;
}

int main() {
    int number, radix;
    cin >> number >> radix;
    vector<int> sequences = getNumber(number, radix);
    if (isPalindromic(sequences)) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }

    for (int i = sequences.size() - 1; i >= 0; --i) {
        cout << sequences[i];
        if (i != 0) {
            cout << " ";
        }
    }
}

1022


这个题目考的是字符串的处理,没有什么特别的地方。但是有个坑的地方,如果id是用int存储,注意需要把7位给补齐了,否则后面三个测试点过不去。我用了一个class来存储数据,keywords数量有点多,怕超时,放在map映射,keywords为key,包含了这个关键字的id放进来,如果查询keyword直接打印map里面的数据即可,不需要遍历了,其他情况就遍历。

//
// Created by GreenArrow on 2020/4/9.
//
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <cstdio>

using namespace std;

map<string, vector<int>> keyWords_id;

class book {
public:
    int ID;
    string title;
    vector<string> keyWords;
    string author;
    string publisher;
    string publish_year;

    book() { keyWords.clear(); }

    book(int id, const string &title, const vector<string> &keyWords, const string &author, const string &publisher,
         const string &publishYear) : ID(id), title(title), keyWords(keyWords), author(author), publisher(publisher),
                                      publish_year(publishYear) {}
};

vector<string> getKeyWords(string keyWords, int id) {
    vector<string> keywords_contain;
    string result;
    for (int i = 0; i < keyWords.size(); ++i) {
        if (keyWords[i] != ' ') {
            result += keyWords[i];
        } else {
            keywords_contain.push_back(result);
            if (keyWords_id.count(result) > 0) {
                keyWords_id[result].push_back(id);
            } else {
                vector<int> ids;
                ids.push_back(id);
                keyWords_id[result] = ids;
            }
            result = "";
        }
    }
    keywords_contain.push_back(result);
    if (keyWords_id.count(result) > 0) {
        keyWords_id[result].push_back(id);
    } else {
        vector<int> ids;
        ids.push_back(id);
        keyWords_id[result] = ids;
    }
    return keywords_contain;
}

void print_vector(vector<int> ids) {
    if (ids.size() == 0) {
        cout << "Not Found" << endl;
        return;
    }
    for (int i = 0; i < ids.size(); ++i) {
        printf("%07d\n", ids[i]);
    }
}

int main() {
    vector<book> books;
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        int id;
        string title;
        string author;
        string keyWords_string;
        string publisher;
        string publish_year;
        cin >> id;
        cin.ignore();
        getline(cin, title);
        getline(cin, author);
        getline(cin, keyWords_string);
        getline(cin, publisher);
        cin >> publish_year;
        cin.ignore();
        vector<string> keyWords = getKeyWords(keyWords_string, id);
        book Book(id, title, keyWords, author, publisher, publish_year);
        books.push_back(Book);
    }

    int m;
    cin >> m;
    cin.ignore();
    for (int j = 0; j < m; ++j) {
        vector<int> result;
        string query;
        getline(cin, query);
        char flag = query[0];
        string target = query.substr(3, query.size() - 3);
        if (flag == '1') {
            for (int i = 0; i < books.size(); ++i) {
                if (books[i].title == target) {
                    result.push_back(books[i].ID);
                }
            }
            sort(result.begin(), result.end());
        } else if (flag == '2') {
            for (int i = 0; i < books.size(); ++i) {
                if (books[i].author == target) {
                    result.push_back(books[i].ID);
                }
            }
            sort(result.begin(), result.end());
        } else if (flag == '3') {
            result = keyWords_id[target];
            sort(result.begin(), result.end());
        } else if (flag == '4') {
            for (int i = 0; i < books.size(); ++i) {
                if (books[i].publisher == target) {
                    result.push_back(books[i].ID);
                }
            }
            sort(result.begin(), result.end());
        } else if (flag == '5') {
            for (int i = 0; i < books.size(); ++i) {
                if (books[i].publish_year == target) {
                    result.push_back(books[i].ID);
                }
            }
            sort(result.begin(), result.end());
        }

        cout << query << endl;
        print_vector(result);
    }
}

算法笔记里面有另一种做法,是用map存储,效果好像更好些。

1023


考的是大数乘法。

char int2string(int num) {
    stringstream ss;
    ss << num;
    return ss.str()[0];
}

void reverse(string &s) {
    for (int i = 0, j = s.size() - 1; i < j; ++i, --j) {
        char c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

string doubleNumber(string s) {
    int addC = 0;
    string S = s;
    reverse(S);
    for (int i = 0; i < S.size(); ++i) {
        char c = S[i];
        int number = (c - '0') * 2 + addC;
        S[i] = int2string(number % 10);
        addC = number / 10;
    }

    if (addC != 0) {
        S += int2string(addC);
    }
    reverse(S);
    return S;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容