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;
}
相關文章
相關標籤/搜索