PAT甲级 模拟题_C++题解

模拟题

PAT (Advanced Level) Practice 模拟题ios

目录

  • 1008 Elevator (20)
  • 1042 Shuffling Machine (20)
  • 1046 Shortest Distance (20)
  • 1051 Pop Sequence (25)
  • 1117 Eddington Number (25)
  • 1128 N Queens Puzzle (20)

1008 Elevator (20)

#include<cstdio>
int main()
{
    int N;
    scanf("%d",&N);
    int currentfloor = 0;
    int nextfloor;
    int time = 5 * N;
    for (int i = 0; i < N; i++){
        scanf("%d", &nextfloor);
        if (nextfloor > currentfloor) time += 6 * (nextfloor - currentfloor);
        if (nextfloor < currentfloor) time += 4 * (currentfloor - nextfloor);
        currentfloor = nextfloor;
    }
    printf("%d", time);
}

1042 Shuffling Machine (20)

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string oldcards[54];
    string newcards[54];
    for (int i = 0; i < 54; i++){
        if (i < 13){
            oldcards[i] = "S";
            oldcards[i].append(to_string(i+1));
        } else if (i < 26){
            oldcards[i] = "H";
            oldcards[i].append(to_string(i+1-13));
        } else if (i < 39){
            oldcards[i] = "C";
            oldcards[i].append(to_string(i+1-26));
        } else if (i < 52){
            oldcards[i] = "D";
            oldcards[i].append(to_string(i+1-39));
        } else {
            oldcards[i] = "J";
            oldcards[i].append(to_string(i+1-52));
        }
    }
    int n;
    cin >> n;
    int order[54];
    for (int i = 0; i < 54; i++) cin >> order[i];
    for (int k = 0; k < n; k++){
        for (int i = 0; i < 54; i++)
            newcards[order[i]-1] = oldcards[i];
        for (int i = 0; i < 54; i++)
            oldcards[i] = newcards[i];
    }
    cout << oldcards[0];
    for (int i = 1; i < 54; i++){
        cout << " " << oldcards[i];
    }
}

1046 Shortest Distance (20)

题目思路

  • 全部结点连起来会造成一个环形,每次输入都从新加一遍距离会超时,即便记录sum每次只算一侧也会超时。
  • 用dis[i]存储第1个结点到第i个结点的下一个结点的距离,sum保存整个路径一圈的总和值。
  • 求得结果就是dis[right – 1] – dis[left – 1]和 sum – dis[right – 1] – dis[left – 1]中较小的那一个
  • 注意:输入两个数没有顺序规定,若是左大右小须要交换
    • 交换可以使用swap函数,许多stl都实现了这一函数,能够用
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    int sum = 0, N, M, a, b, temp, d;
    scanf("%d",&N);
    int distance[N+1] = {0};
    for (int i = 1; i <= N; i++){
        scanf("%d", &temp);
        sum += temp;
        distance[i] = sum;
    }
    scanf("%d", &M);
    for (int i = 0; i < M; i++){
        scanf("%d%d", &a, &b);
        if (a > b) swap(a, b);
        d = distance[b-1] - distance[a-1];
        printf("%d\n", min(d, sum-d));
    }
    return 0;
}

1051 Pop Sequence (25)

栈模拟

  • 无论是否已经判断出可不可能,要先把输入的序列接收进来。因此开一个数组先用一趟循环接受本次全部输入。
  • 按顺序1~n把数字进栈,每进入一个数字,判断有没有超过最大范围
    • 超过了说明到此压栈弹栈操做使得栈内元素大于规定容量,break。
    • 若是没超过,检查是否须要弹出
      • 压栈循环外设置变量 current 记录检查到输入序列的第几个。
      • 每次将栈顶元素与输入序列检查到的对应位置是否相等,while相等则一直弹出且current后移。
      • 若栈顶元素与序列不符或栈已经弹空,则继续压栈新数字。
      • 注意:在while条件中要把!pop.empty()放在&&前,即先检查栈是否为空,不然在栈空时访问pop.top()是非法行为
  • 若是压栈弹栈操做始终使得栈容不超过规定值,应当会检查到输入序列的最后,若current没有到达n+1,说明有元素没有被检查到,栈未被弹空,应输出NO,反之输出YES
#include<cstdio>
#include<stack>
using namespace std;
int main()
{
    int m, n, k;
    scanf("%d%d%d", &m, &n, &k);
    for (int i = 0; i < k; i++){
        int seq[n+1];
        stack<int> pop;
        for (int j = 1; j < n+1; j++) scanf("%d", seq+j);
        int current = 1;
        for (int j = 1; j < n+1; j++){
            pop.push(j);
            if (pop.size() > m) break;
            while (!pop.empty() && pop.top() == seq[current]){
                pop.pop();
                current++;
            }
        }
        if (current < n+1) printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}

1117 Eddington Number (25)

题目思路

  • 在数组中存储n天的千米数,从大到小排序
  • i+1 表示了第几天骑车,那么知足 dis[i] > i + 1 的最大 i 即为所求
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int n, i;
    scanf("%d", &n);
    int dis[n];
    for (i = 0; i < n; i++) scanf("%d", &dis[i]);
    sort(dis, dis+n, greater<int>());
    for (i = 0; i < n; i++)
        if (dis[i] <= i + 1) break;
    printf("%d\n", i);
    return 0;
}

1128 N Queens Puzzle (20)

题目思路

  • 无论是否已经判断出是否为解,要先把输入的序列接收进来。因此开一个数组先用一趟循环接受本次全部输入。
  • 对于第j个数字,判断其前输入的数字中是否有在同一行的 seq[j] == seq[k] 和在斜对角线上的 abs(seq[j]-seq[k]) == abs(j-k)
  • 不知足改变标记变量break离开检查循环,根据标记变量进行对应输出
  • 简化代码:若不知足标记变量不继续进行循环,可将标记变量写入for循环条件。
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
    int K, n;
    scanf("%d", &K);
    for (int i = 0; i < K; i++){
        bool issolution = true;
        scanf("%d", &n);
        int seq[n+1] = {0};
        for (int j = 1; j < n+1; j++) scanf("%d", seq+j);
        for (int j = 1; j < n+1 && issolution; j++){
            for (int k = 1; k < j; k++){
                if (seq[j] == seq[k] || abs(seq[j]-seq[k]) == abs(j-k)){
                    issolution = false;
                    break;
                }
            }
        }
        printf("%s", issolution ? "YES\n" : "NO\n");
    }
    return 0;
}
相关文章
相关标签/搜索