PAT (Advanced Level) Practice 甲级 顶级题目

PAT甲级题目

1001 A+B Format (20 分)

1001 A+B Format (20 分)

  • 题意:给定两个整数a和b,返回答案a+b要求千位分隔符
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;

string solve(string s)
{
    reverse(s.begin(), s.end());
    string ans = "";
    int n = s.size();
    int cnt = 0;
    for (int i = 0; i < n; i++)
    {
        ans += (s[i]);
        if (++cnt % 3 == 0 && i != (n - 1))
            ans += ",";
    }
    reverse(ans.begin(), ans.end());
    return ans;
}

signed main()
{
    int a, b;
    cin >> a >> b;
    if (a + b < 0)
        cout << "-";
    cout << solve(to_string(abs(a + b)));
}
1002 A+B for Polynomials (25 分)

1002 A+B for Polynomials (25 分)

  • 题意:多项式相加,共两行输入,每一行第一个数字是项数,之后每两个数字a和b构成一个ab,然后要求输出两个多项式相加的答案
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;

struct cmp
{
    bool operator()(const int &x, const int &y)
    {
        return x > y;
    }
};
map<int, double, cmp> mp;

int n, x, Ans = 0;
double y;
void solve(int n)
{
    while (n--)
    {
        cin >> x >> y;
        mp[x] += y;
    }
}
signed main()
{
    cin >> n;
    solve(n);
    cin >> n;
    solve(n);
    for (auto t : mp)
        if (t.second)
            Ans++;
    cout << Ans;
    for (auto t : mp)
        if (t.second)
            printf(" %d %.1f", t.first, t.second);
}
1003 Emergency (25 分)

1003 Emergency (25 分)

  • 题意:给定n,m,s,t分别为总点数,总边数,起点,终点,然后一行输入每一个城市的人数,之后m行输入每一条边,询问时s->t的最短路径的数量和在所有最短路径中可以召集的最多人数
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10, M = N * 2;
int dist[N], vis[N], peo[N], sum[N];
int ne[M], e[M], h[N], w[N], idx;
void add(int u, int v, int c)
{
    e[idx] = v;
    ne[idx] = h[u];
    w[idx] = c;
    h[u] = idx++;
}
int perple[N];
void dij(int s, int t)
{
    memset(dist, 0x3f, sizeof dist);
    dist[s] = 0;
    peo[s] = perple[s];
    sum[s] = 1;
    priority_queue<PII, vector<PII>, greater<PII>> que;
    que.push({dist[s], s});
    while (que.size())
    {
        PII q = que.top();
        que.pop();
        int ver = q.second, distance = q.first;
        if (vis[ver])
            continue;
        vis[ver] = 1;

        for (int i = h[ver]; i != -1; i = ne[i])
        {
            int j = e[i];

            if (dist[j] > dist[ver] + w[i])
            {
                dist[j] = dist[ver] + w[i];
                peo[j] = perple[j] + peo[ver];
                que.push(make_pair(dist[j], j));
                sum[j] = sum[ver];
            }
            else if ((dist[j] == dist[ver] + w[i]))
            {
                sum[j] += sum[ver];
                if (peo[j] < peo[ver] + perple[j])
                {
                    peo[j] = peo[ver] + perple[j];
                    que.push(make_pair(dist[j], j));
                }
            }
        }
    }
}

signed main()
{
    int n, m, s, t;
    cin >> n >> m >> s >> t;
    for (int i = 0; i < n; i++)
    {
        h[i] = -1;
        cin >> perple[i];
    }
    while (m--)
    {
        int u, v, w;
        cin >> u >> v >> w;
        add(u, v, w);
        add(v, u, w);
    }
    dij(s, t);
    cout << sum[t] << " " << peo[t];
}
1004 Counting Leaves (30 分)

1004 Counting Leaves (30 分)

  • 题意:给定一棵树,输入n,m分别为树的总点数和非叶子节点数,之后m行输入第一个数是父亲节点编号,第二个数cnt为儿子节点,然后cnt个结点为儿子节点的编号,询问每一个深度的叶子节点数量
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = N;

int h[N], e[M], ne[M], idx;
void add(int u, int v)
{
    e[idx] = v;
    ne[idx] = h[u];
    h[u] = idx++;
}

int va[N], Max_depth;

void dfs(int u, int depth)
{
    Max_depth = max(Max_depth, depth);
    if (h[u] == -1)
    {
        va[depth]++;
        return;
    }
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        dfs(j, depth + 1);
    }
}

signed main()
{
    int n, m;
    cin >> n >> m;
    memset(h, -1, sizeof h);
    for (int i = 0; i < m; i++)
    {
        int u, v, num;
        cin >> u >> num;
        while (num--)
        {
            cin >> v;
            add(u, v);
        }
    }

    dfs(1, 0);
    cout << va[0];
    for (int i = 1; i <= Max_depth; i++)
        cout << " " << va[i];
}
1005 Spell It Right (20 分)

1005 Spell It Right (20 分)

  • 题意:输入一个整数a<10100,询问每一位的数字相加的和,用英文输出
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;

map<int, string> mp;
string s[N] = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "zero"};
signed main()
{
    for (int i = 1; i <= 10; i++)
        mp[i % 10] = s[i - 1];
    string s;
    cin >> s;
    int ans = 0;
    for (int i = 0; i < s.size(); i++)
        ans += (s[i] - '0');

    s = to_string(ans);
    cout<<mp[s[0] - '0'];
    for (int i = 1; i < s.size(); i++)
        cout <<" "<< mp[s[i] - '0'];
}
1006 Sign In and Sign Out (25 分)

1006 Sign In and Sign Out (25 分)

  • 题意:给定n行字符串,每一行分别是人名,到达时间,离开时间,询问最早到达和最晚离开的人名
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;

string a, b;
string AA = "25", BB = "00:00:00";
signed main()
{
    int n;
    cin >> n;
    while (n--)
    {
        string name, time_arrive, time_leave;
        cin >> name >> time_arrive >> time_leave;
        if (AA > time_arrive)
        {
            AA = time_arrive;
            a = name;
        }
        if (BB < time_leave)
        {
            BB = time_leave;
            b = name;
        }
    }
    cout << a << " " << b;
}
1007 Maximum Subsequence Sum (25 分)

1007 Maximum Subsequence Sum (25 分)

  • 题意:输入n个数,询问最大连续子序列的和,该序列的第一个数和最后一个数
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 10;

int a[N], dp[N], pre[N];
signed main()
{
    int n, f = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        if (a[i] >= 0)
            f = 1;
    }
    if (!f)
        return cout << 0 << " " << a[1] << " " << a[n], 0;

    for (int i = 1; i <= n; i++)
    {
        if (a[i] < dp[i - 1] + a[i])
        {
            dp[i] = dp[i - 1] + a[i];
            pre[i] = pre[i - 1];
        }
        else
        {
            dp[i] = a[i];
            pre[i] = i;
        }
    }
    int M = -1;
    for (int i = 1; i <= n; i++)
    {
        if (M < dp[i])
        {
            f = i;
            M = dp[i];
        }
    }
    cout << dp[f] << " " << a[pre[f]] << " " << a[f];
}
1008 Elevator (20 分)

1008 Elevator (20 分)

  • 题意:给定一个整数n,每上一步需要6s 下一步需要4s 每一次停止再启动需要5s的时间,起始点是0,询问总共多少s
/*made in zzh*/
#include <bits/stdc++.h>
using namespace std;
signed main()
{
    int n, x, now, ans = 0;
    cin >> n;
    while (n--)
    {
        int x;
        cin >> x;
        if (x > now)
            ans += (x - now) * 6 + 5;
        else
            ans += (now - x) * 4 + 5;
        now = x;
    }
    cout << ans << endl;
}
1009 Product of Polynomials 分数 25

1009 Product of Polynomials 分数 25

  • 题意:给定两个多项式,首先是整数n,后面n对(e,c)分别表示多项式的指数和系数。求解两个多项式相乘结果
#include <bits/stdc++.h>
using namespace std;
vector<double> a(1010, 0), b(1010, 0), c(2010, 0);
vector<pair<int, double>> ans;
signed main()
{
    int n, m;
    cin >> n;
    while (n--)
    {
        int e;
        double c;
        cin >> e >> c;
        a[e] = c;
    }
    cin >> m;
    while (m--)
    {
        int e;
        double c;
        cin >> e >> c;
        b[e] = c;
    }
    for (int i = 0; i <= 1000; i++)
        for (int j = 0; j <= 1000; j++)
            c[i + j] += (a[i] * b[j]);

    int sum = 0;
    for (int i = 0; i <= 2010; i++)
        if (c[i] != 0)
        {
            sum++;
            ans.push_back(make_pair(i, c[i]));
        }

    reverse(ans.begin(), ans.end());
    cout << sum;
    for (auto t : ans)
        printf(" %d %.1f", t.first, t.second);
}
1010 Radix 分数 25

1010 Radix 分数 25

  • 题意:给定两个字符串,如果op为1,最后一个数就是第一个字符串的进制数,否则是第二个进制数,问是否存在最小的可以使s1 == s2的进制数
#include <bits/stdc++.h>
using namespace std;

#define int long long
const int INF = 1e18;

int solve(string s, int j)
{
    int sum = 0;
    int len = s.size();
    for (int i = 0; i < len; i++)
    {
        if (sum >= INF / j)
            return INF;
        if (s[i] <= '9' && s[i] >= '0')
            sum = sum * j + s[i] - '0';
        else
            sum = sum * j + s[i] - 'a' + 10;
    }
    if (sum < 0)
        return INF;
    return sum;
}

int wor(string s)
{
    int ans = 0;
    int len = s.size();
    for (int i = 0; i < len; i++)
    {
        if (s[i] <= '9' && s[i] >= '0')
            ans = max(ans, (int)s[i] - '0');
        else
            ans = max(ans, (int)s[i] - 'a' + 10);
    }
    return ans + 1;
}

signed main()
{
    int b = 0;
    string s1, s2;
    int op, tag;
    cin >> s1 >> s2 >> op >> tag;
    if (op == 2)
        swap(s1, s2);

    int a = solve(s1, tag);

    int l = wor(s2);
    int r = max(l, a + 1);
    while (l < r)
    {
        int mid = (l + r) / 2;
        if (solve(s2, mid) >= a)
            r = mid;
        else
            l = mid + 1;
    }
    if (solve(s2, l) == a)
        cout << l << endl;
    else
        cout << "Impossible\n";
}
1011 World Cup Betting 分数 20

1011 World Cup Betting 分数 20

  • 题意:公式(max×65%−1)×2,输入就是三行,找每一行最大值,*起来带入max输出就行,数字顺序是W T L
#include <bits/stdc++.h>
using namespace std;

const int N = 2e3 + 10;

int cnt[5];
signed main()
{
    map<int, string> mp;
    mp[0] = "W";
    mp[1] = "T";
    mp[2] = "L";
    double ans = 1;
    for (int i = 0; i < 3; i++)
    {
        double c = -10000;
        for (int j = 0; j < 3; j++)
        {
            double x;
            cin >> x;
            c = max(c, x);
            if (c == x)
                cnt[i] = j;
        }
        ans *= c;
    }
    for (int i = 0; i < 3; i++)
        cout << mp[cnt[i]] << " ";
    printf("%.2f", (ans * 0.65 - 1) * 2);
}
1012 The Best Rank 分数 25

1012 The Best Rank 分数 25

  • 题意:给定n行ID名,C,M,E。A定义为C,M和E的平均值,排序的优先级为A>C>M>E,然后查找对应ID的最高排名,有并列特判。
#include <bits/stdc++.h>
using namespace std;
const int N = 2010;
struct node
{
    int id;
    double score[5];
    int ans = 10;
    string S;
} a[N];
map<int, string> mp = {
    {0, "A"},
    {1, "C"},
    {2, "M"},
    {3, "E"}};
int now = 0;

bool cmp(node a, node b)
{
    return a.score[now] > b.score[now];
}

signed main()
{
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i].id >> a[i].score[1] >> a[i].score[2] >> a[i].score[3];
        a[i].score[0] = (a[i].score[1] + a[i].score[2] + a[i].score[3]) / 3.0;
    }

    for (; now < 4; now++)
    {
        sort(a, a + n, cmp);
        for (int i = 0; i < n; i++)
        {
            // 可以直接将前面的继承过来
            int rank = i;
            while (rank--)
                if (a[i].score[now] != a[rank].score[now])
                    break;

            if (rank + 2 < a[i].ans)
            {
                a[i].ans = rank + 2;
                a[i].S = mp[now];
            }
        }
    }
    while (m--)
    {
        int id, flag = 0;
        cin >> id;
        for (int i = 0; i < n; i++)
            if (a[i].id == id)
            {
                cout << a[i].ans << " " << a[i].S << endl;
                flag = 1;
                break;
            }

        if (!flag)
            cout << "N/A\n";
    }
}
1013 Battle Over Cities 分数 25

1013 Battle Over Cities 分数 25

  • 题意:给定n个点,m条路,k个询问,询问是删除编号id的点,为了使图联通需要新增几条路
#include <bits/stdc++.h>
using namespace std;

const int N = 1e3 + 10, M = 2 * N * N;

int h[N], e[M], ne[M], idx;
int st[N];

void add(int u, int v)
{
    e[idx] = v;
    ne[idx] = h[u];
    h[u] = idx++;
}

void dfs(int u)
{
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (st[j] == -1 || st[j] == 1)
            continue;
        st[j] = 1;
        dfs(j);
    }
}

signed main()
{
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++)
        h[i] = -1;
    for (int i = 0; i < m; i++)
    {
        int u, v;
        cin >> u >> v;
        add(u, v);
        add(v, u);
    }
    while (k--)
    {
        int ans = 0;
        memset(st, 0, sizeof st);
        int x;
        cin >> x;
        st[x] = -1;
        for (int i = 1; i <= n; i++)
        {
            if (i == x)
                continue;
            if (st[i] == 0)
            {
                dfs(i);
                ans++;
            }
        }
        cout << ans - 1 << "\n";
    }
}
1014 Waiting in Line 分数 30

1014 Waiting in Line 分数 30

  • 题意:n个窗口,每一个窗口可以排队m人,总共k个人,每一个人需求时是正整数,然后q次询问。排队规则是队伍人数一样长的时候,排编号最小的队伍,否则去队伍人数最少的队伍排队。然后对于17:00之后的请求不再处理,只处理[8:00,17:00)之间的请求,而且如果处理完成时间大于17:00,也要给出一个目标时间(一定合法,不会超级大)。
1015 Reversible Primes 分数 20

1015 Reversible Primes 分数 20

  • 题意:给定10进制数字n,d,判断10进制n和反转后的d进制的n是否为素数。
#include <bits/stdc++.h>
using namespace std;
#define int long long

int solve(string a, int b) // 将b进制的a 转化成10进制的now
{
    int now = 0;
    for (int i = 0; i < (int)a.size(); i++)
        now = now * b + a[i] - '0';
    return now;
}

string solve_tran(int a, int b) // 将10进制的a 转化成b进制的now
{
    string now = "";
    while (a)
    {
        now += to_string(a % b);
        a /= b;
    }
    return now;
}

int isprime(int a)
{
    int m = sqrt(a);
    for (int i = 2; i <= m; i++)
        if (a % i == 0)
            return 0;
    return !(a == 1);
}

signed main()
{
    string n;
    int d;
    while (cin >> n >> d)
    {
        if (n[0] == '-')
            break;
        string c = solve_tran(atoll(n.c_str()), d);
        int p = solve(c, d);
        if (isprime(atoll(n.c_str())) && isprime(p))
            cout << "Yes\n";
        else
            cout << "No\n";
    }
}
1016 Phone Bills 分数 25

1016 Phone Bills 分数 25

  • 题意:给定24小时的价格,单位是美分/分钟,然后给定n个任务(无序),首先是任务的受理人,之后是任务的发生时间,最后是任务的类型,on-line是开始,off-line是结束,同时会存在非法任务,对于多次任务的开始,只记录最后一次,对于多次任务的结束,只记录最初一次。问每一个受理人的使用时间和价钱,价钱为0的受理人不输出。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e4 + 10;
int money[30], SUM[N], n, month;
map<string, vector<string>> mp;

int solve(string a, string b)
{
    int d = atoll(a.substr(0, 2).c_str()), d1 = atoll(b.substr(0, 2).c_str());
    int h = atoll(a.substr(0 + 3, 2).c_str()), h1 = atoll(b.substr(0 + 3, 2).c_str());
    int m = atoll(a.substr(0 + 6, 2).c_str()), m1 = atoll(b.substr(0 + 6, 2).c_str());
    return ((d - d1) * 60 * 24 + (h - h1) * 60 + (m - m1));
}
double work(string a, string b)
{
    int d = atoll(a.substr(0, 2).c_str()), d1 = atoll(b.substr(0, 2).c_str());
    int h = atoll(a.substr(0 + 3, 2).c_str()), h1 = atoll(b.substr(0 + 3, 2).c_str());
    int m = atoll(a.substr(0 + 6, 2).c_str()), m1 = atoll(b.substr(0 + 6, 2).c_str());
    return (double)(SUM[(d)*60 * 24 + (h)*60 + m] - SUM[(d1)*60 * 24 + (h1)*60 + m1]);
}

struct node
{
    string name, val, op;
} a[N];
bool cmp(node a, node b)
{
    return a.val < b.val;
}

signed main()
{
    for (int i = 1; i <= 24; i++)
        cin >> money[i];
    for (int i = 1; i <= 31; i++) // 利用前缀和进行预处理
        for (int j = 1; j <= 24; j++)
            for (int k = 1; k <= 60; k++)
                SUM[(i - 1) * 60 * 24 + (j - 1) * 60 + k] = SUM[(i - 1) * 60 * 24 + (j - 1) * 60 + k - 1] + money[j];
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> a[i].name;
        scanf("%lld:", &month);
        cin >> a[i].val >> a[i].op;
    }
    sort(a, a + n, cmp);

    for (int i = 0; i < n; i++)
        if (a[i].op == "on-line")
        {
            if (mp[a[i].name].size() % 2)
                mp[a[i].name].back() = a[i].val;
            else
                mp[a[i].name].push_back(a[i].val);
        }
        else if (a[i].op == "off-line" && (mp[a[i].name].size() % 2))
            mp[a[i].name].push_back(a[i].val);
    for (auto t : mp)
    {
        vector<string> now = t.second;
        double sum = 0;
        for (int i = 0; i + 1 < (int)now.size(); i += 2)
            sum += work(now[i + 1], now[i]);
        if (sum > 0)
        {
            cout << t.first << " ";
            if (month < 10)
                cout << "0";
            cout << month << endl;
            for (int i = 0; i + 1 < (int)now.size(); i += 2)
            {
                cout << now[i] << " " << now[i + 1] << " " << solve(now[i + 1], now[i]) << " ";
                printf("$%.2f\n", work(now[i + 1], now[i]) / 100.00);
            }
            printf("Total amount: $%.2f\n", sum / 100.00);
        }
    }
}
1017 Queueing at Bank 分数 25

1017 Queueing at Bank 分数 25

  • 题意:给定n个任务,每一行给出开始时间,持续时间,仅有k个机器可以运行任务,询问平均等待时间。机器工作时间是8点到17点,17点之后到达的任务不再运行。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e4 + 10;

int sub(string a, string b)
{
    int d = atoll(a.substr(0, 2).c_str()), d1 = atoll(b.substr(0, 2).c_str());
    int h = atoll(a.substr(0 + 3, 2).c_str()), h1 = atoll(b.substr(0 + 3, 2).c_str());
    int m = atoll(a.substr(0 + 6, 2).c_str()), m1 = atoll(b.substr(0 + 6, 2).c_str());
    return ((d - d1) * 60 * 60 + (h - h1) * 60 + (m - m1));
}
string To_string(int s)
{
    if (s < 10ll)
        return ("0" + to_string(s));
    return to_string(s);
}
string solve(string a, int b)
{
    int h = atoll(a.substr(0, 2).c_str());
    int m = atoll(a.substr(0 + 3, 2).c_str());
    int s = atoll(a.substr(0 + 6, 2).c_str());
    h += ((m + b) / 60);
    m = (m + b) % 60;
    return (To_string(h) + ":" + To_string(m) + ":" + To_string(s));
}

struct node
{
    string t;
    int p;
} a[N];
bool cmp(node a, node b)
{
    return a.t < b.t;
}

signed main()
{
    int n, k, ans = 0;
    cin >> n >> k;
    for (int i = 0; i < n; i++)
        cin >> a[i].t >> a[i].p;
    sort(a, a + n, cmp);

    priority_queue<string, vector<string>, greater<string>> que;
    for (int i = 0; i < n; i++)
    {
        if (a[i].t < "08:00:00")
        {
            ans += sub("08:00:00", a[i].t);
            a[i].t = "08:00:00";
        }
        if (a[i].t >= "17:00:01")
        {
            n = i;
            break;
        }
        if (que.size() < k)
            que.push(solve(a[i].t, a[i].p));
        else
        {
            string now = que.top();
            que.pop();
            if (now > a[i].t)
                ans += (sub(now, a[i].t));
            que.push(solve(max(now, a[i].t), a[i].p));
        }
    }
    printf("%.1f\n", round(ans / 6.0 / n) / 10.0);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pig2687

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值