后记:考完 PTA 乙级了,92 分人麻了,字符串的题永远的痛呜呜呜呜(

# 注意点

  • 规定几位输出老老实实输出几位,比如规定 id4 位数就 %04d,限制好域宽,不然前导 0 没了!!这个经常吃亏
    • 典型题:1065 单身狗 (25 分)1072 开学寄语 (20 分)
  • 同理,需要去掉前导 0 的时候不要犹豫:1074 宇宙无敌加法器 (20 分)
  • printf 输出 % 的时候用 %%(不会吧不会吧不会只有我忘了吧)
  • 注意数据范围,选好用什么类型,有时候需要用 long long
  • 字符串题 getline 用烂()
  • 基本上反反复复就用那么几个 vector、map,尤其是 map 的 find 函数(
  • 注意边界,为 0,为最大值,重复等情况,

# 好题推荐

  • 1003 我要通过! (20 分) 看到这个通过率就明白了。
  • 1013 数素数 (20 分) 经典埃式筛法求素数,练习一下。
  • 1014 福尔摩斯的约会 (20 分) 典型的好玩的字符串题。
  • 1024 科学计数法 (20 分) 字符串解析,坑点挺多,记得补 0,分正负等
  • 1034 有理数四则运算 (20 分) gcd、lcm、最简分数 (其实 lcm 没用上,不过作为一个练习了)
  • 1035 插入与归并 (25 分) 好题啊好题.jpg,考到了插入排序和归并排序,个人感觉挺难的一道题
  • 1040 有理数四则运算 (20 分) 字符串,dp
  • 1045 快速排序 (25 分) 说是快排,其实是找一个元素其左边元素都比他小,右边都比他大,即找主元
  • 1049 数列的片段和 (20 分) 思维题,找规律
  • 1050 螺旋矩阵 (25 分) 蓝桥杯模拟赛做过,模拟一下这个过程即可
  • 1055 集体照 (25 分) 坑点较多,可以一做,结构体。
  • 1073 多选题常见计分法 (20 分),是之前 1058 的选择题 plus 版本,感觉可以当 25 分题了(
  • 1074 宇宙无敌加法器 (20 分) 考到了进制和大整数加法,我愿称之为好题
  • 1075 链表元素分类 (25 分) 直接用 vector 模拟链表,注意结点不在链表中的情况 。1070-1075 这一套题挺好的
  • 1078 字符串压缩与解压 (20 分) 字符串处理的好题
  • 1080 MOOC 期终成绩 (25 分) 典型结构体、重载排序规则
  • 1084 外观数列 (20 分), 题意读懂就很简单,核心思想类同于 1078 中的字符串压缩,一个个处理
  • 1090 危险品装箱 (25 分) 有坑点,但我不说,哎就是玩(

# 1003 我要通过! (20 分)

  • 1003 我要通过! (20 分) 看到这个通过率就明白了。
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
    int T;
    string s;
    cin >> T;
    while(T--) {
        cin >> s;
        map<char, int> m;   //PAT 各自的数量
        int vp = 0, vt = 0;
        int len = s.length();
        for(int i = 0; i < len; ++i) {
            m[s[i]]++;
            if(s[i] == 'P') vp = i;
            if(s[i] == 'T') vt = i;
        }
        if(m.size() == 3 && m['P'] == 1 && m['T'] == 1 
        && vt-vp != 1 && vp * (vt-vp-1) == len - vt - 1)
            cout << "YES" << endl;
        else cout << "NO" << endl;
    }
    return 0;
}

# 1013 数素数 (20 分)

  • 1013 数素数 (20 分) 经典埃式筛法求素数,练习一下。
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 9000000;
int a[maxn]={0};// 素数数组 是则为 0
int ans[10001];// 全是素数
int main() {
    int m, n, k = 0;
    cin >> m >> n;
    for (int i = 2; i < maxn; i++){
        if(a[i] == 1) continue;
        ans[k++] = i;
        for(ll j = (ll)i * i; j < maxn; j += i) a[j] = 1;
    }
    int cnt = 0;
    for(int i = m-1; i <= n-1; i++) {
        cnt++;
        cout << ans[i];
        if(i == n-1) {
            cout << endl;
            break;
        }
        if(cnt%10 == 0) cout << endl;
        else cout << " ";
    }
    return 0;
}

# 1014 福尔摩斯的约会 (20 分)

  • 1014 福尔摩斯的约会 (20 分) 典型的好玩的字符串题。
#include <iostream>
#include <cstdio>
using namespace std;
string day[7] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};
int h, m;
char date;
char hour;
string input[4];
int main() {
    for(int i = 0; i < 4; ++i)
        cin >> input[i];
    int len1 = input[0].length();
    int len2 = input[1].length();
    int len = min(len1, len2);
    int k = 0;
    for(int i = 0; i < len; ++i) {
        char ch = input[0].at(i);
        if(ch >= 'A' && ch <= 'G') {
            if(ch == input[1].at(i)) {
                date =  ch;
                k = i;
                break;
            }
        };
    }
    for(int i = k+1; i < len; ++i) {
        char ch = input[0].at(i);
        if((ch >= 'A' && ch <= 'N') || (ch >= '0' && ch <= '9')) {
            if(ch == input[1].at(i)) {
                hour =  ch;
                break;
            }
        };
    }
    if(hour >= '0' && hour <= '9') h = hour - '0';
    else h = hour - 'A' +10;
    int len3 = input[2].length();
    int len4 = input[3].length();
    len = min(len3, len4);
    for(int i = 0; i < len; ++i) {
        char ch = input[2].at(i);
        if((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z')) {
            if(ch == input[3].at(i)) {
                m = i;
                break;
            } 
        };
    }
    cout << day[date-'A'];
    printf(" %02d:%02d", h, m);
    return 0;
}

# 1024 科学计数法 (20 分)

  • 1024 科学计数法 (20 分) 字符串解析,坑点挺多,记得补 0,分正负等
#include <iostream>
#include <algorithm>
#include <string>
#include <sstream>
using namespace std;
typedef long long ll;
string str;
string ans;
int ei;
int s2i(string str) {
    int x;
    stringstream ss;
    ss << str;
    ss >> x;
    return x;
}
int main() {
    cin >> str;
    int len = str.length();
    if(str[0] == '-') cout << '-';
    ei = str.find('E');
    string A = str.substr(1, ei-1);
    int lenA = A.length();
    int h = s2i(str.substr(ei+2, len-ei-1));
    if(h == 0) {
        cout << A;
    } else if(str[ei+1] == '-') {
        cout << "0.";
        --h;
        for(int i = 0; i < h; ++i)
            cout << '0';
        for(int i = 0; i < lenA; ++i) {
            if(A[i] == '.') continue;
            cout << A[i];
        }
    } else if(str[ei+1] == '+') {
        cout << A[0];
        for(int i = 2; i < lenA; ++i) {
            cout << A[i];
            --h;
            if(h == 0 && i+1 < lenA) cout << '.'; 
        }
        int len0 = h-(lenA-2)+1;
        for(int i = 0; i < len0; ++i) 
            cout << '0';
    }
    return 0;
}

# 1034 有理数四则运算 (20 分)

  • 1034 有理数四则运算 (20 分) gcd、lcm (其实 lcm 没用上,不过作为一个范例了)
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {
    return a%b == 0? b: gcd(b, a%b);
}
ll lcm(ll a, ll b) {
    return (a*b)/gcd(a,b);
}
// k ta/tb
void solve(ll a, ll b) { // 4 -12
    if(a*b == 0) {
        if(!b) printf("Inf");
        else if(!a) printf("0");
        return;
    }
    int flag = 0;
    ll k = a/b; // 0
    ll ta = a;
    ll tb = b;
    if((a>0 && b<0) || (a<0 && b>0)) {// 异号
        flag = 1;
        if(a < 0) a *= -1;//
        if(b < 0) b *= -1;
    } else if(a < 0 && b < 0){
        a *= -1, b *= -1;
    }
    // a 4 b 2
    ll t = gcd(a%b, b);
    if(k || !flag) {
        ta = (a%b)/t;
        tb = b / t;
    } else { // !k && flag
        if(ta > 0 && tb < 0) {
            ta = -1*(a%b)/t;
            tb = b/t;
        } else {
            ta = (ta%tb)/t;
            tb = tb / t;
        }
    }
    if(flag) {// 为负数
        if(ta == 0) {
            printf("(%lld)", k);
            return;
        }
        if(k) {
            printf("(%lld %lld/%lld)", k, ta, tb);
        } else {
            printf("(%lld/%lld)", ta, tb);
        }
    } else {
        if(ta == 0) {
            printf("%lld", k);
            return;
        }
        if(k) {
            printf("%lld %lld/%lld", k, ta, tb);
        } else printf("%lld/%lld", ta, tb);
    }
}
ll a1, b1, a2, b2;
int main() {
    scanf("%lld/%lld %lld/%lld", &a1, &b1, &a2, &b2);
    solve(a1, b1);
    printf(" + ");
    solve(a2, b2);
    printf(" = ");
    ll lc = lcm(b1, b2);
    solve(a1*(lc/b1)+a2*(lc/b2), lc);
    printf("\n");
    
    solve(a1, b1);
    printf(" - ");
    solve(a2, b2);
    printf(" = ");
    solve(a1*(lc/b1)-a2*(lc/b2), lc);
    printf("\n");// ohhhhhhhh
    
    solve(a1, b1);
    printf(" * ");
    solve(a2, b2);
    printf(" = ");
    solve(a1*a2, b1*b2);
    printf("\n");
    
    solve(a1, b1);
    printf(" / ");
    solve(a2, b2);
    printf(" = ");
    solve(a1*b2, a2*b1);
    printf("\n");
    return 0;
}

# 1035 插入与归并 (25 分)

  • 1035 插入与归并 (25 分) 好题啊好题.jpg,考到了插入排序和归并排序,个人感觉挺难的一道题
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 110;
int N;
ll a[maxn], A[maxn], b[maxn];
bool isSame(ll a[], int N) {
    for(int i = 0; i < N; ++i) {
        if(a[i] != A[i]) return false;
    }
    return true;
}
bool Insert_sort(ll a[], int N) {
    bool flag = false;
    for(int p = 1; p < N; ++p) {
        ll t = a[p];
        int i;
        for(i = p; i > 0 && a[i-1] > t; --i) {
            a[i] = a[i-1];
        }
        a[i] = t;
        if(flag) return true;
        if(isSame(a, N)) {
            flag = true;
            continue;
        }
    }
    return false;
}
void Merge(ll a[], ll tmp[], int s, int m, int e) {
    int pb = s;
    int p1 = s, p2 = m;
    while(p1 <= m-1 && p2 <= e) {
        if(a[p1] <= a[p2]) tmp[pb++] = a[p1++];
        else tmp[pb++] = a[p2++];
    }
    while(p1 <= m-1)
        tmp[pb++] = a[p1++];
    while(p2 <= e)
        tmp[pb++] = a[p2++];
    for(int i = 0; i < e-s+1; ++i)
        a[s+i] = tmp[i];
}
void Merge_Pass(ll a[], ll b[], int N, int len) {
    // 按 len 长度切分 归并到 b
    int i;
    for(i = 0; i <= N-2*len; i+=2*len) 
        Merge(a, b, i, i+len, i+2*len-1);
    if(i+len < N) Merge(a, b,i, i+len, N-1);// 剩 2 个子列
    else for(int j = i; j < N; ++j) b[j] = a[j];
}
void Merge_Sort(ll a[], int N) {
    bool flag = false;
    int len = 1;
    ll tmp[maxn];
    while(len < N) {
        Merge_Pass(a, tmp, N, len);
        len *= 2;
        if(isSame(tmp, N)) flag = true;
        else if(flag) return;
        Merge_Pass(tmp, a, N, len);
        len *= 2;
        if(isSame(a, N)) flag = true;
        else if(flag) return;
    }
}
int main() {
    scanf("%d", &N);
    for(int i = 0; i < N; ++i) {
        scanf("%lld", &a[i]);
        b[i] = a[i];
    }
    for(int i = 0; i < N; ++i) {
        scanf("%lld", &A[i]);
    }
    if(Insert_sort(a, N)) {
        printf("Insertion Sort\n");
    } else {
        for(int i = 0; i < N; ++i) 
            a[i] = b[i];
        Merge_Sort(a, N);
        printf("Merge Sort\n");
        
    }
    for(int i = 0; i < N; ++i) {
        printf(" %lld"+!i, a[i]);
    }
    return 0;
}

# 1040 有几个 PAT (25 分)

  • 1040 有理数四则运算 (20 分) 字符串,dp
// PPAATTPATTAP
#include <iostream>
#include <string>
using namespace std;
string s;
int dp[100010][3];
int main() {
    cin >> s;
    int len = s.length();
    if(s[0] == 'P') dp[0][0] = 1;
    for(int i = 1; i < len; ++i) {
        if(s[i] == 'P') dp[i][0] = dp[i-1][0]+1;
        else dp[i][0] = dp[i-1][0];
        if(s[i] == 'A') dp[i][1] = dp[i-1][1]+dp[i-1][0];
        else dp[i][1] = dp[i-1][1];
        if(s[i] == 'T') dp[i][2] = dp[i-1][2]+dp[i-1][1];
        else dp[i][2] = dp[i-1][2];
        dp[i][0] %= 1000000007;
        dp[i][1] %= 1000000007;
        dp[i][2] %= 1000000007;
    }
    cout << dp[len-1][2];
    return 0;
}

# 1045 快速排序 (25 分)

  • 1045 快速排序 (25 分) 说是快排,其实是找一个元素其左边元素都比他小,右边都比他大,即找主元
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100005;
int N;
vector<ll> ans;
ll a[maxn];
bool l[maxn], r[maxn];
ll maxx, minx;
int main() {
    cin >> N;
    maxx = a[0];
    l[0] = true;
    for(int i = 0; i < N; ++i) 
        cin >> a[i];
    for(int i = 1; i < N; ++i) {
        if(a[i] < maxx) {
            l[i] = false;
        } else {
            l[i] = true;
            maxx = a[i];
        }
    }
    minx = a[N-1];
    r[N-1] = true;
    for(int i = N-2; i >= 0; --i) {
        if(a[i] > minx) {
            r[i] = false;
        } else {
            r[i] = true;
            minx = a[i];
        }
    }
    for(int i = 0; i < N; ++i) {
        if(l[i] && r[i]) ans.push_back(a[i]);
    }
    sort(ans.begin(), ans.end());
    int len = ans.size();
    cout << len << endl;
    for(int i = 0; i < len; ++i) {
        printf(" %lld"+!i, ans[i]);
    }
    cout << endl;
    return 0;
}

# 1049 数列的片段和 (20 分)

  • 1049 数列的片段和 (20 分) 思维题,找规律
#pragma GCC optimize(2)
#include <iostream>
using namespace std;
const int maxn = 100005;
int N;
long double a[maxn];
long double ans;
int main() {
    cin >> N;
    for(int i = 0; i < N; ++i) {
        cin >> a[i];
        ans += (i+1.0)*(N-i)*a[i];
    }
    printf("%.2llf\n", ans);
    return 0;
}

# 1050 螺旋矩阵 (25 分)

  • 1050 螺旋矩阵 (25 分) 蓝桥杯模拟赛做过,模拟一下这个过程即可
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 10005;
int N, m, n, t, nowi, nowj;
int a[maxn];
int b[maxn][maxn];
int main() {
    cin >> N;
    int k = sqrt(N);
    for(int i = 1; i <= k; ++i) {
        if(N % i == 0) {
            n = i, m = N / i;
        } else continue;
    }
    for(int i = 0; i < N; ++i) cin >> a[i];
    sort(a, a+N, greater<int>());
    b[nowi][nowj] = a[t++];
    while(t < N) {
        while(nowj+1 < n && !b[nowi][nowj+1]) { // 右
            b[nowi][++nowj] = a[t++];
        } 
        while(nowi+1 < m && !b[nowi+1][nowj]) { // 下
            b[++nowi][nowj] = a[t++];
        } 
        while(nowj-1 >= 0 && !b[nowi][nowj-1]) {// 左
            b[nowi][--nowj] = a[t++];
        } 
        while(nowi-1 >= 0 && !b[nowi-1][nowj]) {// 上
            b[--nowi][nowj] = a[t++];
        } 
    }
    for(int i = 0; i < m; ++i) {
        for(int j = 0; j < n; ++j) {
            printf(" %d"+!j, b[i][j]);
        }
        printf("\n");
    }
    return 0;
}

# 1055 集体照 (25 分)

  • 1055 集体照 (25 分) 坑点较多,可以一做,结构体。
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <deque>
using namespace std;
const int maxn = 10005;
int N, K, k;
struct Person {
    string name;
    int height;
    bool operator<(const Person& p1) {
        if(height != p1.height) return height < p1.height;
        return name > p1.name;
    }
} p;
vector<Person> v;
stack<deque<Person>> ans;
// 175 188 190 186
// 168 170 168
// 160 160 159
void solve(vector<Person> t) {
    deque<Person> newt;
    int len = t.size();
    int nowp = len-1;
    newt.push_back(t[nowp--]);
    while(nowp >= 0) {
        newt.push_front(t[nowp--]);
        if(nowp < 0) break;
        newt.push_back(t[nowp--]);
    }
    ans.push(newt);
}
int main() {  
    cin >> N >> K;
    for(int i = 0; i < N; ++i) {
        cin >> p.name >> p.height;
        v.push_back(p);
    }
    sort(v.begin(), v.end());
    k = N / K;
    int i = 0;
    while(i < N) {
        vector<Person> t;
        for(int j = i; j < i+k; ++j) t.push_back(v[j]); 
        i += k;
        if(i+k > N) {
            for(int j = i; j < N; ++j) 
                t.push_back(v[j]); 
            i += k;
        }
        solve(t);
    }
    while(!ans.empty()) {
        deque<Person> d = ans.top();
        cout << d[0].name;
        for(int i = 1; i < d.size(); ++i)
            cout << ' ' << d[i].name;
        cout << endl;
        ans.pop();
    }
    return 0;
}
// 6 2
// sss 190
// die 202 
// wjc 120
// abs 180
// bsw 180
// fwr 100

# 1073 多选题常见计分法 (20 分)

  • 1073 多选题常见计分法 (20 分),是之前 1058 的选择题 plus 版本,感觉可以当 25 分题了(
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <sstream>
using namespace std;
typedef long long ll;
const int maxn = 1005;
const int maxm = 105;
int N, M, ct;
struct Choice {
    int id, falcnt;
    char val;
    bool operator<(const Choice& c1) {
        if(falcnt != c1.falcnt) return falcnt > c1.falcnt;
        if(id != c1.id) return id < c1.id;
        return val < c1.val;
    }
} c[maxn];
map<string, int> m;
struct Title {
    int id, falcnt;
    int sumg, cnt, rcnt;
    string allr;
    map<char, int> rindex;
    Title():allr(""){}
    bool operator<(const Title& t1) {
        return falcnt != t1.falcnt ? falcnt > t1.falcnt: id < t1.id;
    }
} t[maxm];
// 3 0 0 0
// 3 2 0 1
// 0 0 5 0
string tran(int id, char ch) {
    stringstream ss;
    string s;
    ss << id << '-' << ch;
    ss >> s;
    return s;
}
int main() { 
    cin >> N >> M;
    for(int i = 0; i < M; ++i) {
        cin >> t[i].sumg >> t[i].cnt >> t[i].rcnt;
        t[i].id = i+1;
        t[i].falcnt = 0;
        for(int j = 0; j < t[i].rcnt; ++j) {
            char ch;
            cin >> ch;
            t[i].rindex[ch] = t[i].allr.size();
            t[i].allr += ch;
        }
        cin.ignore();
        // cout << t[i].allr << endl;
    }
    // 
    for(int i = 0; i < N; ++i) {
        int total;     // 学生选择的选项数
        char nowc;
        double sum = 0;
        for(int j = 0; j < M; ++j) {// 每个多选题
            int flag = 2; // 0 1 2 代表错误 部分正确 全对
            vector<int> v;
            for(int k = 0; k < t[j].rcnt; ++k) v.push_back(0);
            scanf("%*c%d", &total);
            if(total != t[j].rcnt)
                flag = 1;
            for(int x = 0; x < total; ++x) { // 每个选项
                scanf("%*c%c", &nowc);
                if(t[j].allr.find(nowc) == string::npos) {  // 错选
                    flag = 0;
                    string s = tran(j, nowc);
                    if(m.find(s) == m.end()) {
                        m[s] = ct;
                        c[ct].id = j+1;
                        c[ct].falcnt = 1;
                        c[ct].val = nowc;
                        ++ct;
                    } else ++c[m[s]].falcnt;
                } else v[t[j].rindex[nowc]] = 1;           
            }
            scanf("%*c%*c");
            if(flag != 2) {// 漏选
                for(int k = 0; k < t[j].rcnt; ++k) {
                    if(v[k] == 0) {
                        // cout << k << ':' << t[j].allr << ':' << t[j].allr[k] << endl;; 
                        string s = tran(j, t[j].allr[k]);
                        if(m.find(s) == m.end()) {
                            m[s] = ct;
                            c[ct].id = j+1;
                            c[ct].falcnt = 1;
                            c[ct].val = t[j].allr[k];
                            ++ct;
                        } else ++c[m[s]].falcnt;
                    }
                }
            }
            if(flag == 2) sum += t[j].sumg;
            else if(flag == 1) sum += (t[j].sumg*1.0/2);
            else continue;
        }
        printf("%.1f\n", sum);
    }
    sort(c, c+ct);
    if(c[0].falcnt == 0 ) cout << "Too simple" << endl;
    else {
        int k = 0;
        while(k+1 < ct && c[k+1].falcnt == c[k].falcnt) ++k;
        for(int i = 0; i <= k; ++i) 
            cout << c[i].falcnt << ' ' << tran(c[i].id, c[i].val) << endl;
    }
    return 0;
}
// 3 4 
// 3 4 2 a c
// 2 5 1 b
// 5 3 2 b c
// 1 5 4 a b d e
// (2 a c) (3 b d e) (2 a c) (3 a b e)
// (2 a c) (1 b) (2 a b) (4 a b d e)
// (1 c) (1 e) (1 c) (4 a b c d)

# 1074 宇宙无敌加法器 (20 分)

  • 1074 宇宙无敌加法器 (20 分) 考到了进制和大整数加法,我愿称之为好题
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 50;
string jw;
string n1, n2;
int main() {
    getline(cin, jw);
    getline(cin, n1);
    getline(cin, n2);
    reverse(jw.begin(), jw.end());
    reverse(n1.begin(), n1.end());
    reverse(n2.begin(), n2.end());
    int N = jw.size();
    int flag = 0;// 进位
    string ans = "";
    if(n1.length() < N) n1.append(N-n1.length(), '0');
    if(n2.length() < N) n2.append(N-n2.length(), '0');
    for(int i = 0; i < N; ++i) {
        int x1 = n1[i]-'0';
        int x2 = n2[i]-'0';
        int d = jw[i]-'0';
        if(d == 0) d = 10;
        int t = x1+x2+flag;
        int x;
        if(t >= d) {
            x = t % d;
            flag = 1;
        } else {
            x = t;
            flag = 0;
        }
        char ch = '0'+x;
        ans += ch;
    }
    if(flag == 1) ans += '1';
    reverse(ans.begin(), ans.end());
    if(ans.find_first_not_of('0') == string::npos) cout << 0 << endl;
    else cout << ans.substr(ans.find_first_not_of('0')) << endl;
    return 0;
}
// 000
// 000
// 00

# 1075 链表元素分类 (25 分)

  • 1075 链表元素分类 (25 分) 直接用 vector 模拟链表,也可以直接写个链表。1070-1075 这一套题挺好的
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 1000005;
int p, N, K, head, x;
struct LNode {
    int val;
    int nowp, next;
} a[maxn], t;
map<int, int> m;
vector<LNode> temp;
vector<LNode> ans;
int main() {
   scanf("%d %d %d", &p, &N, &K);
   for(int i = 0; i < N; ++i) {
       scanf("%d %d %d", &a[i].nowp, &a[i].val, &a[i].next);
       m[a[i].nowp] = i;
       if(a[i].nowp == p) head = i;
   }
   x = head;
   while(a[x].next != -1) {
       temp.push_back(a[x]);
       x = m[a[x].next];
   }
   temp.push_back(a[x]);
   int len1 = temp.size();
//    cout << len1 << endl;
   for(int i = 0; i < len1; ++i)
       if(temp[i].val < 0) ans.push_back(temp[i]);
   for(int i = 0; i < len1; ++i)
       if(temp[i].val >= 0 && temp[i].val <= K) ans.push_back(temp[i]);
   for(int i = 0; i < len1; ++i)
       if(temp[i].val >= 0 && temp[i].val > K) ans.push_back(temp[i]);
    int len2 = ans.size();
    for(int i = 0; i < len2; ++i) {
        if(i == len2-1) printf("%05d %d -1\n", ans[i].nowp, ans[i].val);
        else printf("%05d %d %05d\n", ans[i].nowp, ans[i].val, ans[i+1].nowp);
    }   return 0;
}

# 1078 字符串压缩与解压 (20 分)

  • 1078 字符串压缩与解压 (20 分) 字符串处理的好题
#include <iostream>
#include <string>
using namespace std;
char ch;
void zip(string s) {
    // cout << "zip";
    char prec = s[0];
    int cnt = 1;
    int len = s.length();
    for(int i = 1; i < len; ++i) {
        if(s[i] == prec) {
            ++cnt;
        } else {
            if(cnt >= 2) cout << cnt;
            cout << prec;
            prec = s[i];
            cnt = 1;
        }
    }
    if(cnt >= 2) cout << cnt;
    cout << prec;
}
void Print(char c, int num) {
    for(int i = 0; i < num; ++i) cout << c;
}
void unzip(string s) {
    // cout << "unzip";
    int len = s.length();
    int cnt = 1;
    char nowc = s[0];
    string nowcnt;
    for(int i = 0; i < len; ++i){
        if(s[i] >= '0' && s[i] <= '9') {
            nowcnt += s[i];
        } else {
            if(nowcnt.length() > 0) cnt = stoi(nowcnt);
            nowc = s[i];
            Print(nowc, cnt);
            cnt = 1;
            nowcnt = "";
        }
    }
}
int main() {
    string str;
    cin >> ch;
    getchar();
    getline(cin, str);
    if(ch == 'C') zip(str);
    else unzip(str);
    return 0;
}
// D
// 10T2h4is i5s a3 te4st CA3a as10Z

# 1080 MOOC 期终成绩 (25 分)

  • 1080 MOOC 期终成绩 (25 分) 典型结构体、重载排序规则
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 1000005;
int P, M, N;
struct Student {
    string name;
    int realg, gp, gm, gf;
    Student():gp(-1), gm(-1), gf(-1),realg(0) {}
    bool operator<(const Student& s1) {
        if(realg != s1.realg) return realg > s1.realg;
        return name < s1.name;
    }
};
vector<Student> v;
vector<Student> ans;
map<string,int> m;
int main() {
    ios::sync_with_stdio(false);
    cin >> P >> M >> N;
    string s;
    int g;
    for(int i = 0; i < P; ++i) {
        Student t;
        cin >> s >> g;
        if(m.find(s) == m.end()) {
            m[s] = v.size();
            t.name = s, t.gp = g;
            v.push_back(t);
        } else v[m[s]].gp = g;
    }
    for(int i = 0; i < M; ++i) {
        Student t;
        cin >> s >> g;
        if(m.find(s) == m.end()) {
            m[s] = v.size();
            t.name = s, t.gm = g;
            v.push_back(t);
        } else v[m[s]].gm = g;
    }
    for(int i = 0; i < N; ++i) {
        Student t;
        cin >> s >> g;
        if(m.find(s) == m.end()) {
            m[s] = v.size();
            t.name = s, t.gf = g;
            v.push_back(t);
        } else v[m[s]].gf = g;
    }
    for(int i = 0; i < v.size(); ++i) {
        if(v[i].gm > v[i].gf) {
            double x = v[i].gm*0.4 + v[i].gf*0.6;
            if((int)(x*10)%10 >= 5) v[i].realg = (int)(x+1);
            else v[i].realg = (int)x;
        }
        else v[i].realg = v[i].gf;
        if(v[i].gp >= 200 && v[i].realg >= 60) ans.push_back(v[i]);
    }
    sort(ans.begin(), ans.end());
    for(auto i: ans) {
        cout << i.name << ' ' << i.gp << ' ' << i.gm << ' ' << i.gf << ' ' << i.realg << endl;
    }
    return 0;
}

# 1084 外观数列 (20 分)

  • 1084 外观数列 (20 分), 题意读懂就很简单,核心思想类同于 1078 中的字符串压缩,一个个处理
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <sstream>
using namespace std;
int N;
string i2s(int x) {
    stringstream ss;
    string str;
    ss << x;
    ss >> str;
    return str;
}
int main() {
    string ans, d;
    cin >> d >> N;
    ans = d;
    for(int i = 1; i < N; ++i){
        string temp = "";
        char prec = ans[0];
        int cnt = 1;
        for(int j = 1; j < ans.length(); ++j) {
            if(ans[j] == ans[j-1]) {
                ++cnt;
            } else {
                temp += prec;
                temp += i2s(cnt);
                cnt = 1;
                prec = ans[j];
            }
        }
        temp += prec;
        temp += i2s(cnt);
        ans = temp;
    }
    cout << ans << endl;
    return 0;
}
// 4 41 4111 41

# 1090 危险品装箱 (25 分)

  • 1090 危险品装箱 (25 分) 有坑点,但我不说,哎就是玩(
#include <iostream>
#include <map>
#include <vector>
using namespace std;
const int maxn = 10006;
int N, M, x1, x2;
map<int, vector<int> > m1;
int main() {
    scanf("%d %d", &N, &M);
    for(int i = 0; i < N; ++i) {
        cin >> x1 >> x2;
        m1[x1].push_back(x2);
        m1[x2].push_back(x1);
    }
    while(M--) {
        cin >> x1;
        map<int, int> m2;
        bool flag = true;
        vector<int> v(x1);
        for(int i = 0; i < x1; ++i) {
            cin >> v[i];
            m2[v[i]] = 1;
        }
        for(int i = 0; i < x1; ++i) {
            if(m1.find(v[i]) == m1.end()) continue;
            int len = m1[v[i]].size();
            for(auto k : m1[v[i]]) {
                if(m2.find(k) != m2.end()) flag = false;
                if(!flag) break;
            }
        }
        if(flag) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;
}

# 感想

PTA 乙级的题目特别抠细节,往往有些题会卡在那么一两个测试点上令人头疼,但只要程序正常写出来了一般能拿到大部分分,最难好像也就考到排序、dp 和一些思维题,没有任何高级算法的出现。最后,善用 STL 基本上就没问题了。

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

cos 微信支付

微信支付

cos 支付宝

支付宝