#PAT甲级:做题汇总,不再更新啦!

博主分享了PAT编程竞赛中多个题目(如1001A+Bformat、1002A+BforPolynomials等)的解题思路和代码实现,涉及算法包括层次遍历、Dijkstra求最短路径、并查集、二分查找等。同时,博主表达了对于编程竞赛和未来职业规划的焦虑与期待,分享了收到名校录取通知的喜悦。
摘要由CSDN通过智能技术生成

随便做做,不知道做啥了,看看没有讲解做成啥样

1001 A + B format

a加b然后按照千分位三个一组输出。

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    int a, b, c;
    bool s = false;
    cin >> a >> b;
    c = a + b;
    vector<int> v;
    if(c < 0)
    {
        c = -c;
        cout << '-';
    }
    int cnt = 0;
    //从低位开始,凑够三位加一个逗号标记,然后正序输出
    // 不断取最低位 while(c) { x = c % 10, c /= 10;}
    while(c)
    {
        if(cnt == 3)
        {
            v.push_back(10);//逗号标记
            cnt = 0;
        }
        v.push_back(c % 10);
        cnt++;
        c = c / 10;
    }

    for(int i = v.size() - 1; i >= 0; i--)
    {
        if(v[i] == 10)
            cout << ',';
        else cout << v[i];
    }
    if(v.size() == 0)
        cout << 0;
    return 0;
}

1002 A+B for Polynomials (25 分)

给了两个多项式的系数和下标,对应位相加即可。
最后要输出不是0的个数 和系数下标

#include<iostream>
using namespace std;
const int N = 1010;
int k, n, cnt;
double p[N], a;
int main()
{
    scanf("%d", &k);
    while(k--)
    {
        scanf("%d %lf", &n, &a);
        if(p[n] == 0)
            cnt++;
        p[n] += a;
        if(p[n] == 0)
            cnt--;
    }
    scanf("%d", &k);
    while(k--)
    {
        scanf("%d %lf", &n, &a);
        if(p[n] == 0)
            cnt++;//cnt实时统计不为0的个数,或者最后统一计算一遍也可
        p[n] += a;
        if(p[n] == 0)
            cnt--;
    }
    printf("%d", cnt);
    int c = 0;
    for(int i = N - 1; i >= 0; i--)
    {
        if(p[i])
            printf(" %d %.1f", i, p[i]);
    }
    return 0;
}

1003 Emergency (25 分) ※

dijsktra求单源最短路径,此题目的要点在于求最短路径的条数和最短路径上最大的队伍和

  • dist[t] + g[t][j] < dist[j] //t和j在一条最短路径上,路径不变,队伍数是前面的t再加上j点处的队伍数
    • dist[j] = dist[t] + g[t][j];
      sum[j] = sum[t] + team[j];
      num[j] = num[t];
  • dist[t] + g[t][j] == dist[j])//经过t到j和不经过t到j的最短路径相同, 这时最短路径就产生了分叉,路径条数相加,队伍数取最大
    • num[j] += num[t];
      sum[j] = max(sum[j], sum[t] + team[j]);
      在这里插入图片描述
#include<iostream>
#include<cstring>
#include<set>
using namespace std;
const int N = 510;
int dist[N], g[N][N], team[N];
int sum[N], num[N]; //num[]表示从c2到各个点最短路径的条数, sum[]表示从c2到各个点最短路径上的队伍个数
bool st[N];
int n, m, c1, c2;

void dijsktra(int& shortest, int& cnt)
{
    memset(dist, 0x3f, sizeof dist);
    dist[c1] = 0;
    sum[c1] = team[c1];
    num[c1] = 1;//保证有一条
    
    for(int i = 0; i < n; i++)
    {
        int t = -1;
        for(int j = 0; j < n; j++)
        {
            if(!st[j] && (t == -1 || dist[j] < dist[t]))
                t = j;
        }
        
        st[t] = true;
        for(int j = 0; j < n; j++)
        {
            if(dist[t] + g[t][j] < dist[j]) //t和j在一条最短路径上,路径不变
            {
                dist[j] = dist[t] + g[t][j];
                sum[j] = sum[t] + team[j];
                num[j] = num[t];
            }
            else if(dist[t] + g[t][j] == dist[j])//经过t到j和不经过t到j的最短路径相同, 路径条数相加,队伍数取最大
            {
                num[j] += num[t];
                sum[j] = max(sum[j], sum[t] + team[j]);
            }
        }
    }
    shortest = num[c2];
    cnt = sum[c2];
}
int main()
{
    int shortest, cnt;
    memset(g, 0x3f, sizeof g);
    scanf("%d%d%d%d", &n, &m, &c1, &c2);
    for(int i = 0; i < n; i++)//是第i个城市拥有的城市数目而不是队伍编号
        scanf("%d", &team[i]);
    while(m--)
    {
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        g[a][b] = w;
        g[b][a] = w;
    }
    dijsktra(shortest, cnt);
    printf("%d %d", shortest, cnt);
    return 0;
}

1004 Counting Leaves (30 分)

层次遍历法 求每一层叶节点的数目

#include<iostream>
#include<cstring>
#include<queue>
#include<unordered_map>
using namespace std;
const int N = 110;
int n, m, a, b, k;
int h[N], e[N], ne[N], idx;


void add(int a, int b)
{
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx;
    idx++;
}
int main()
{
    memset(h, -1, sizeof h);
    unordered_map<int, int> hashset; //保存非叶节点,用unordered_set更好其实
    scanf("%d %d", &n, &m);
    while(m--)
    {
        scanf("%d %d", &a, &k);
        hashset[a] = k;
        while(k--)
        {
            scanf("%d", &b);
            add(a, b);
        }
    }

    queue<int> q;
    q.push(1);

    int flag = false;
    while(q.size())
    {
        int si = q.size(), cnt = 0;
        for(int i = 0; i < si; i++)
        {
            int t = q.front();
            q.pop();
            if(!hashset.count(t))
                cnt++;//每层中统计一次个数
            for(int i = h[t]; i != -1; i = ne[i])
            {
                int j = e[i];
                q.push(j);
            }
        }
        if(flag)
            printf(" %d", cnt);
        else
        {
            printf("%d", cnt);
            flag = true;
        }
    }
    return 0;
}

1005 Spell It Right (20 分)

算大数的各个数位之和

#include<iostream>
#include<vector>
using namespace std;
//各个位置数相加不会超过int

int main()
{
    string a;
    vector<int> A;
    int sum = 0;
    cin >> a;

    for(int i = a.size() - 1; i >= 0; i--)
        sum += a[i] - '0';
    while(sum)
    {
        A.push_back(sum % 10);
        sum /= 10;
    }
    //输出
    string out[10] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
    int n = A.size();
    for(int i = n - 1; i >= 0; i--)
    {
        if(i == n - 1)
            cout << out[A[i]];
        else
            cout << " " << out[A[i]] ;
    }
    if(n == 0)
        cout << "zero";
    return 0;
}

1006 Sign In and Sign Out (25 分)

日期转换

#include<iostream>
#include<climits>
using namespace std;

int main()
{
    int n, h1, m1, s1, h2, m2, s2;
    string name;
    cin >> n;
    
    int mi = INT_MAX, ma = INT_MIN;
    string unlock, lock;
    while(n--)
    {
        cin >> name;
        scanf("%d:%d:%d %d:%d:%d", &h1, &m1, &s1, &h2, &m2, &s2);
        int t1 = h1 * 3600 + m1 * 60 + s1;
        int t2 = h2 * 3600 + m2 * 60 + s2;
        if(t1 < mi)
        {
            mi = t1;
            unlock = name;
        }
        if(t2 > ma)
        {
            ma = t2;
            lock = name;
        }
    }
    cout << unlock << " " << lock;
    return 0;
}

二次遍历-前缀和过了,无语总是看不清题意,我以为输出下标,结果是数

#include<iostream>
#include<climits>
using namespace std;
const int N = 1e4 + 10;
int a[N], sum[N];
int n, s, k;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        sum[i] = sum[i - 1] + a[i];
        //printf("%d ", sum[i]);
        if(a[i] < 0)
            k++;
    }
    int ma = INT_MIN, ml = 0, mr = 0;
    for(int i = 1; i <= n; i++)
    {
        for(int j = i; j <= n; j++)
        {
            if(sum[j] - sum[i - 1] > ma)
            {
                ml = i, mr = j;
                ma = sum[j] - sum[i - 1];
            }
        }
    }
    if(k == n)
        printf("0 %d %d", a[1], a[n]);
    else
        printf("%d %d %d", ma, a[ml], a[mr]);
    return 0;
}

一次遍历代码(柳神)※

#include<iostream>
#include<climits>
using namespace std;
const int N = 1e4 + 10;
int a[N];
int n, k;

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        if(a[i] < 0)
            k++;
    }
    int ml = 1, mr = n, sum = INT_MIN, tmp = 0, tmpl = 1;
    for(int i = 1; i <= n; i++)
    {
        tmp += a[i];
        if(tmp < 0)//临时和小于0了,舍弃前面统计的这些,临时左下标tmpl从i的下一个开始
        {
            tmp = 0;
            tmpl = i + 1;
        }
        else if(tmp > sum)//临时和大于sum了,更新此时和和位置
        {
            sum = tmp;
            ml = tmpl;
            mr = i;
        }
    }
    if(k == n)
        printf("0 %d %d", a[1], a[n]);
    else
        printf("%d %d %d", sum, a[ml], a[mr]);
    return 0;
}

1008 Elevator (20 分)

20分的都太easy

#include<iostream>
using namespace std;
int main()
{
    int n, f, t = 0, s = 0;
    cin >> n;
    while(n--)
    {
        cin >> f;
        if(t < f)
            s += (f - t) * 6;
        else
            s += (t - f) * 4;
        s += 5;
        t = f;
    }
    printf("%d", s);
    return 0;
}

1009 Product of Polynomials (25 分)

乘法结果要开两倍

#include<iostream>
using namespace std;
const int N = 2010;
double a[N], c[N];
int n1, n2, x, cnt;

int main()
{
    double k;
    scanf("%d", &n1);
    while(n1--)
    {
        scanf("%d %lf", &x, &k);
        a[x] = k;
    }
    scanf("%d", &n2);
    while(n2--)
    {
        scanf("%d %lf", &x, &k);
        for(int i = 0; i < N; i++)
        {
            if(a[i])
                c[i + x] += k * a[i];
        }
    }
    for(int i = 0; i < N; i++) 
    {
        if(c[i])
            cnt++;
    }
    printf("%d", cnt);
    for(int i = N - 1; i >= 0; i--) 
    {
        if(c[i])
            printf(" %d %.1f", i, c[i]);
    }
    return 0;
}

1010 Radix (25 分) ※

有点难,主要是情况复杂需要考虑清楚
y总二分模板yyds!

#include<iostream>
#include<ctype.h>
#include<algorithm>
using namespace std;

long long convert(string s, long long r)
{
    long long ans = 0;
    for(int i = 0; i < s.size(); i++)
    {
        int t = isdigit(s[i])? s[i] - '0': s[i] - 'a' + 10;
        ans = ans * r + t;
    }
    return ans;
}

int main()
{
    string n1, n2, x;
    int tag;
    long long radix, N1, N2; 
    cin >> n1 >> n2 >> tag >> radix;
    if(tag == 2) //n1为已知进制数字,n2为未知进制数字
        x = n1, n1 = n2, n2 = x;
    N1 = convert(n1, radix);

    char ma_char = '0'; //求出n2中最大字符
    for(int i = 0; i < n2.size(); i++)
        if(n2[i] > ma_char)
            ma_char = n2[i];

    int ma_num = isdigit(ma_char)? ma_char - '0': ma_char - 'a' + 10;
    //96549157373046880 10 1 10,输出应该是96549157373046880
    //n1可能很大,导致上届很大,进制很大,转换就可能越界long long变成负数
    long long l = ma_num + 1;//左边界最小为x中最大字符+ 1 ab:最小为c,12进制
    long long r = max(l, N1); //x不能超过N1,最小两位数10的最大进制只能到N1进制,转换成十进制这就已经是N1了,再大的进制都不可能了
                            //一位数的话,可能n1比n2的最小进制还要小,比如n1=1, n2=1, radix = 2,最小进制是2,和n1取max
    while(l < r)
    {
        long long mid = l + r + 1 >> 1;
        N2 = convert(n2, mid);
        if(N2 < 0 || N2 > N1)
            r = mid - 1;//false
        else
            l = mid;//right
    }
    if(N1 == convert(n2, l))
        printf("%d", l);
    else
        printf("Impossible");
    return 0;
}

1011 World Cup Betting (20 分)

题目看不懂,没意思的一道题

#include<iostream>
using namespace std;
int main()
{
    char g[3] = {'W', 'T', 'L'};
    double x, ans = 1;
    for(int i = 0; i < 3; i++)
    {
        double ma = 0;
        int idx = 0;
        for(int j = 0; j < 3; j++)
        {
            scanf("%lf", &x);
            if(x > ma)
            {
                ma = x;
                idx = j;
            }
        }
        printf("%c ", g[idx]);
        ans = ans * ma;
    }
    printf("%.2f", (ans * 0.65 - 1) * 2);
    return 0;
}

下面先只做25和30分的非模拟题

1013 Battle Over Cities (25 分)

并查集算连通块数量做的,垃圾为啥不给M范围,测试点4边巨大。看来是个稠密图,用邻接矩阵快一些。
在这里插入图片描述

#include<iostream>
#include<cstring>
using namespace std;
const int N = 1010;
int n, m, k, a, b, x;
int g[N][N], father[N];
int find(int x)
{
    if(father[x] != x)
        father[x] = find(father[x]);
    return father[x];
}
int main()
{
    scanf("%d%d%d", &n, &m, &k);
    memset(g, 0x3f, sizeof g);
    while(m--)
    {
        scanf("%d%d", &a, &b);
        g[a][b] = 1;
        g[b][a] = 1;
    }
    while(k--)
    {
        scanf("%d", &x);
        int cnt = n - 1;
        for(int i = 1; i <= n; i++)
            father[i] = i;
        for(int i = 1; i <= n; i++)
        {
            if(i == x) continue;
            for(int j = 1; j <= n; j++)
            {
                a = i, b = e[j];
                //cout << a << b << endl;
                if(b == x || g[a][b] == 0x3f3f3f3f) continue;
                int fa = find(a), fb = find(b);
                if(fa != fb)
                {
                    father[fa] = fb;
                    cnt--;
                }
            }
        }
        if(k == 0)
            printf("%d", cnt - 1);
        else
            printf("%d\n", cnt - 1);
    }
    return 0;
}

柳神DFS思路:n次迭代,看能dfs几次,就说明有几个不连通,nice!

#include<iostream>
#include<cstring>
using namespace std;
const int N = 1010;
int n, m, k, a, b, x;
int g[N][N];
bool st[N];

void dfs(int x)
{
    st[x] = true;
    for(int i = 1; i <= n; i++)
        if(!st[i] && g[x][i] == 1)
            dfs(i);
}
int main()
{
    scanf("%d%d%d", &n, &m, &k);
    memset(g, 0x3f, sizeof g);
    while(m--)
    {
        scanf("%d%d", &a, &b);
        g[a][b] = 1;
        g[b][a] = 1;
    }
    while(k--)
    {
        scanf("%d", &x);
        int cnt = 0;
        memset(st, false, sizeof st);
        st[x] = true;

        for(int i = 1; i <= n; i++)
            if(!st[i])
            {
                dfs(i);cnt++;
            }
        
        if(k == 0)
            printf("%d", cnt - 1);
        else
            printf("%d\n", cnt - 1);
    }
    return 0;
}

1015 Reversible Primes (20 分)

想着复习一下素数筛法
进制转换 + 素数判断

#include<iostream>
#include<vector>
using namespace std;
const int N = 1e7;
bool st[N];
//埃式筛法
void get_prime()
{
    st[1] = true, st[0] = true;//测试点2
    for(int i = 2; i < N; i++)
    {
        if(!st[i])
        {
            for(int j = i + i; j < N; j = j + i)
                st[j] = true;
        }
    }
}
int main()
{
    int n, r;
    get_prime();
    while(1)
    {
        scanf("%d", &n);
        if(n < 0)
            break;
        scanf("%d", &r);
        if(st[n])
        {
            printf("No\n");
            continue;
        }
        vector<int> inverse;
        //从十进制转换成r进制
        while(n)
        {
            inverse.push_back(n % r);
            n = n / r;
        }
        //从r进制转换成十进制
        int in = 0;
        for(int i = 0; i < inverse.size(); i++)
        {
            in = in * r + inverse[i];
        }
        //cout << in << endl;
        if(!st[in])
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

线性筛法

int prime[N], cnt;
bool st[N];

void get_prime()
{
   st[1] = true;
    for(int i = 2; i < N; i++)
    {
        if(!st[i])
            prime[cnt++] = i;
        for(int j = 0; prime[j] < N / i; j++)
        {
            st[prime[j] * i] = true;
            if(i % prime[j] == 0)
                break;
        }
    }
}

1018 Public Bike Management (30 分)

累了这道题
首先dijkstra找到最短路径的前驱节点

  • if(dist[t] + g[t][j] < dist[j])
    • pre[j].clear();
      pre[j].push_back(t);
  • else if(dist[t] + g[t][j] == dist[j])
    • pre[j].push_back(t);

dfs统计mi_need和mi_back
真的很恶心,不能用总的-完美的,因为不能用后面的补前面,所以还是得一个一个来!

#include<iostream>
#include<cstring>
#include<climits>
#include<vector>
using namespace std;


const int N = 510;
int bike[N], dist[N], b[N];
int g[N][N];
bool st[N];
vector<vector<int>> pre(N);
vector<int> tmppath, path;
int cm, n, m, sp, u, v, w;
int sum = 0, cnt = 0, mi_need = INT_MAX, mi_back = INT_MAX;

//记录前驱节点
int dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[0] = 0;

    for(int i = 0; i <= n; i++)
    {
        int t = -1;
        for(int j = 0; j <= n; j++)
        {
            if(!st[j] && (t == -1 || dist[t] > dist[j]))
                t = j;
        }
        st[t] = true;

        for(int j = 0; j <= n; j++)
        {
            if(dist[t] + g[t][j] < dist[j])
            {
                dist[j] = min(dist[j], dist[t] + g[t][j]);
                pre[j].clear();
                pre[j].push_back(t);
            }
            else if(dist[t] + g[t][j] == dist[j])
            {
                dist[j] = min(dist[j], dist[t] + g[t][j]);
                pre[j].push_back(t);
            }
        }
    }
    return dist[sp];
}

void dfs(int u)
{
    tmppath.push_back(u);
    if(u == 0)
    {
        int prefect = cm / 2 , back = 0, need = 0;
        //可以用前面缺的车补后面,但不能用后面补前面
        for(int i = tmppath.size() - 2; i >= 0; i--)
        {
            v = tmppath[i];
            if(bike[v] < prefect)
            {
                if(back > prefect - bike[v])
                    back -= (prefect - bike[v]);
                else
                {
                    need += ((prefect - bike[v]) - back);
                    back = 0;
                }
            }
            else
                back += (bike[v] - prefect);
        }
        
        if(need < mi_need)
        {
            mi_need = need;
            path = tmppath;
            mi_back = back;
        }
        else if(need == mi_need && back < mi_back)
        {
            mi_back = back;
            path = tmppath;
        }
        tmppath.pop_back();//pop 0
        return ;
    }
    for(int i = 0; i < pre[u].size(); i++)
        dfs(pre[u][i]);
    tmppath.pop_back();
}

int main()
{
    cin >> cm >> n >> sp >> m;
    for(int i = 1; i <= n; i++)
        scanf("%d", &bike[i]);
    memset(g, 0x3f, sizeof g);
    while(m--)
    {
        scanf("%d %d %d", &u, &v, &w);
        g[u][v] = g[v][u] = w;
    }
    int x = dijkstra();

    //tmppath.push_back(sp);
    dfs(sp);
    printf("%d 0", mi_need);
    for(int i = path.size() - 2; i >= 0; i--)
        printf("->%d", path[i]);
    printf(" %d", mi_back);
    return 0;
}

靠 ! 没保存!

1020 Tree Traversals (25 分)

中序+ 后序构建二叉树,然后层次遍历
easy

#include<iostream>
#include<queue>
using namespace std;
const int N = 35;
int in[N], out[N], ans[N];
int n, idx;
struct Node
{
    int val;
    Node* left;
    Node* right;
    Node(int v)
    {
        val = v;
        left = right = nullptr;
    }
};

Node* construct(int li, int ri, int lo, int ro)
{
    if(li > ri || lo > ro)
        return nullptr;
    Node* root = new Node(out[ro]);
    int inid = 0;//中序中rootid
    for(int i = li; i <= ri; i++)
    {
        if(out[ro] == in[i])
        {
            inid = i;
            break;
        }
    }
    int leftsize = inid - li, rightsize = ri - inid;
    root->left = construct(li, inid - 1, lo, lo + leftsize - 1);
    root->right = construct(inid + 1, ri, lo + leftsize, ro - 1);
    return root;
}

void bfs(Node * root)
{
    queue<Node*> q;
    q.push(root);
    while(q.size())
    {
        Node * t = q.front();
        q.pop();
        ans[idx++] = t->val;

        if(t->left != nullptr)
            q.push(t->left);
        if(t->right != nullptr)
            q.push(t->right);
    }
}
int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        scanf("%d", &out[i]);
    for(int i = 1; i <= n; i++)
        scanf("%d", &in[i]);
    Node* root = construct(1, n, 1, n);
    bfs(root);
    printf("%d", ans[0]);
    for(int i = 1; i < n; i++)
        printf(" %d", ans[i]);
    return 0;
}

1021 Deepest Root (25 分)

找到根最深的root

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

const int N = 100010;
int h[N], e[N], ne[N], idx;
int n, u, v, cnt = 0;
bool st[N];
int height[N];
void add(int u, int v)
{
    e[idx] = v; ne[idx] = h[u]; h[u] = idx; idx++;
}

void dfs(int u)
{
    st[u] = true;
    for(int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if(!st[j])
            dfs(j);
    }
}
int bfs(int u)
{
    memset(st, false, sizeof st);
    queue<int> q;
    q.push(u);
    st[u] = true;
    int ans = 1;
    while(q.size())
    {
        int qn = q.size();
        for(int i = 0; i < qn; i++)
        {
            int t = q.front();
            q.pop();
            for(int j = h[t]; j != -1; j = ne[j])
            {
                v = e[j];
                if(!st[v])
                {
                    q.push(v);
                    st[v] = true;
                }
            }
        }
        ans++;
    }
    return ans;
}
int main()
{
    scanf("%d", &n);
    memset(h, -1, sizeof h);
    for(int i = 1; i < n; i++)
    {
        scanf("%d %d", &u, &v);
        add(u, v);
        add(v, u);
    }
    //DFS找连通块数量
    for(int i = 1; i <= n; i++)
    {
        if(!st[i])
        {
            dfs(i);
            cnt++;
        }
    }
    if(cnt > 1)
    {
        printf("Error: %d components", cnt);
        return 0;
    }
    //BFS找高度最大的
    int ma = 0;
    for(int i = 1; i <= n; i++)
    {
        height[i] = bfs(i);
        ma = max(ma, height[i]);
    }
    for(int i = 1; i <= n; i++)
        if(height[i] == ma)
            printf("%d\n", i);
    return 0;
}

1022 Digital Library (30 分)

最后一个测试点没过

#include<iostream>
#include<sstream>
using namespace std;
#include<map>
#include<set>

int main()
{
    int n, m;
    string line, id, year, title, author, keyword, publisher;
    multimap<string, string> myear, mtitle, mauthor, mkeyword, mpublisher;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        cin >> id;
        getchar();
        getline(cin, title);
        getline(cin, author);
        getline(cin, keyword);
        getline(cin, publisher);
        cin >> year;
        getchar();

        mtitle.insert(make_pair(title, id));
        myear.insert(make_pair(year, id));
        mauthor.insert(make_pair(author, id));
        istringstream skeyword(keyword);
        string word;	
        while(skeyword >> word)
            mkeyword.insert(make_pair(word, id));
        mpublisher.insert(make_pair(publisher, id));
    }
    scanf("%d", &m);
    getchar();
    while(m--)
    {
        getline(cin, line);
        cout << line << endl;
        string str = line.substr(3, line.size() - 3);
        switch (line[0])
        {
        case '1':
            {
                auto nums = mtitle.count(str); 
                auto iter = mtitle.find(str);
                if(nums == 0) cout << "Not Found\n";
                while(nums--)
                {
                    cout << iter->second << endl;
                    iter++;
                }
                break;
            }
        case '2':
            {
                auto nums = mauthor.count(str); 
                auto iter = mauthor.find(str);
                if(nums == 0) cout << "Not Found\n";
                while(nums--)
                {
                    cout << iter->second << endl;
                    iter++;
                }
                break;
            }
        case '3':
            {
                auto nums = mkeyword.count(str); 
                auto iter = mkeyword.find(str);
                if(nums == 0) cout << "Not Found\n";
                set<string> setkey;
                while(nums--)
                {
                    setkey.insert(iter->second);
                    iter++;
                }
                for(auto tmp: setkey)
                    cout << tmp << endl;
                break;
            }
        case '4':
            {
                auto nums = mpublisher.count(str); 
                auto iter = mpublisher.find(str);
                if(nums == 0) cout << "Not Found\n";
                while(nums--)
                {
                    cout << iter->second << endl;
                    iter++;
                }
                break;
            }
        case '5':
            {
                auto nums = myear.count(str); 
                auto iter = myear.find(str);
                if(nums == 0) cout << "Not Found\n";
                while(nums--)
                {
                    cout << iter->second << endl;
                    iter++;
                }
                break;
            }
        default:
            break;
        }
    }
    return 0;
}

1024 Palindromic Number (25 分)

回文判断 + 大整数加法

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 50;
bool check(vector<int>& a)
{
    int an = a.size();
    int i = 0, j = an - 1;
    while(i < j) //不能等于 可能i > j
    {
        if(a[i] != a[j])
            return false;
        i++, j--;
    }
    return true;
}

vector<int> add(vector<int>& a, vector<int> & b)
{
    vector<int> c;
    int an = a.size(), bn = b.size();
    int t = 0;
    for(int i = 0; i < an || i < bn; i++)
    {
        if(i < an)
            t += a[i];
        if(i < bn)
            t += b[i];
        c.push_back(t % 10);
        t = t / 10;
    }
    if(t)
        c.push_back(t);
    return c;
}


int main()
{
    string a;
    int k, cnt = 0;
    vector<int> A;
    cin >> a >> k;
    for(int i = a.size() - 1; i >= 0; i--)
        A.push_back(a[i] - '0');
    while(!check(A) && cnt < k)
    {
        vector<int> B;
        for(int i = A.size() - 1; i >= 0; i--)
            B.push_back(A[i]);
        A = add(A, B);
        cnt++;
    }
    for(int i = A.size() - 1; i >= 0; i--)
        printf("%d", A[i]);
    cout << endl << cnt;
    return 0;
}

1028 List Sorting (25 分)

结构体+ sort排序 easy

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
struct stu
{
    string id, name;
    int grade;
}Stu[N];

bool cmp1(const stu& a, const stu& b)
{
    return a.id < b.id;
}

bool cmp2(const stu& a, const stu& b)
{
    if(a.name != b.name)
        return a.name < b.name;
    return a.id < b.id;
}

bool cmp3(const stu& a, const stu& b)
{
    if(a.grade != b.grade)
        return a.grade < b.grade;
    return a.id < b.id;
}
int main()
{
    int n, c;
    cin >> n >> c;
    for(int i = 0; i < n; i++)
        cin >> Stu[i].id >> Stu[i].name >> Stu[i].grade;
    switch (c)
    {
    case 1:
        sort(Stu, Stu + n, cmp1);
        break;
    case 2:
        sort(Stu, Stu + n, cmp2);
        break;
    case 3:
        sort(Stu, Stu + n, cmp3);
        break;
    default:
        break;
    }
    for(int i = 0; i < n; i++)
        cout << Stu[i].id << " " << Stu[i].name << " " << Stu[i].grade << endl;
    return 0;
}

28号推免结束后再见 ! 希望希望! 好运好运! 再给我最后一次好运吧 ! !
最近总是焦虑的不行,因为我非常清楚自己的职业规划,甚至在每一步都想好了大概要做什么。但是当你达不到或者有机会但是发现太难了的时候,你就会陷入深深的焦虑、难过与不自信中。都到这个时候了,保研都进行两个月了。该做的都做得差不多了,剩下的就是别紧张,放轻松,能行就行不行就算了吧,可能自己的水平还不够,下一个阶段在努力吧!
28号见!
————————————————————————————————————————
29号更新!幸运来得太突然,接连收到浙大、复旦、北大软微的复试通知,由于冲突,选择二度放弃复旦面试。最终获得了浙大、北大软微的offer,去北京啦!PAT也没太用上!但是我相信一切都是缘分!感谢自己!感谢大家!PAT也就不会再更新啦!祝大家心想事成嘿嘿!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值