2018年秋PTA乙級回顧

距離上次我一我的參加PAT考試已通過去快一個學期了,想一想上次本身也是搞笑,本身一我的被這個書包就去了ZZ,人生地不熟的,乘坐公交車還坐反了。考完試由於不知道要等到考試結束就能夠領取成績證書,本身連那張不及格的證書都沒有領,就急着趕火車回到了學校。由於這個週末就參加考試了,因此考試前作幾道題熟悉一下試題的難度。ios

 

今天再作一下上次沒有作出來的題目發現,這些題真的沒涉及到什麼算法,都是一些基礎的模擬題,但是有些數據卡的我是不知所措,因此也很可貴滿分。算法

 

1086 就不告訴你 (15 分)

作做業的時候,鄰座的小盆友問你:「五乘以七等於多少?」你應該不失禮貌地圍笑着告訴他:「五十三。」本題就要求你,對任何一對給定的正整數,倒着輸出它們的乘積。數組

53.jpg

輸入格式:

輸入在第一行給出兩個不超過 1000 的正整數 A 和 B,其間以空格分隔。安全

輸出格式:

在一行中倒着輸出 A 和 B 的乘積。函數

輸入樣例:

5 7

輸出樣例:

53

 

題解:測試

首先將數字轉換成字符串,而後用reverse翻轉字符串,去掉字符串前面的0,而後輸出就行了。google

代碼:spa

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

int main() {
    int x, y, i;

    cin >> x >> y;

    string ans = to_string(x*y);

    reverse(ans.begin(), ans.end());

    for (i = 0; i < ans.length(); ++i) if (ans[i] != '0') break;
    
    for (; i < ans.length(); ++i) cout << ans[i];
    cout << endl;

    return 0;
}

  

1087 有多少不一樣的值 (20 分)

當天然數 n 依次取 一、二、三、……、N 時,算式 n/2+n/3+n/5⌋ 有多少個不一樣的值?(注:x⌋ 爲取整函數,表示不超過 x 的最大天然數,即 x 的整數部分。).net

輸入格式:

輸入給出一個正整數 N(2N104​​)。3d

輸出格式:

在一行中輸出題面中算式取到的不一樣值的個數。

輸入樣例:

2017

輸出樣例:

1480

 

題解:

用set去重,最後返回set容器的size便可。

代碼:

#include<iostream>
#include<set>

using namespace std;

int main() {
    int n; 
    cin >> n;

    set<int> ans;
    for (int i = 1; i <= n; ++i) {
        int temp = i/2 + i/3 + i/5;
        ans.insert(temp);
    }

    cout << ans.size() << endl;
    
    return 0;
}

  

 

  

1088 三人行 (20 分)

子曰:「三人行,必有我師焉。擇其善者而從之,其不善者而改之。」

本題給定甲、乙、丙三我的的能力值關係爲:甲的能力值肯定是 2 位正整數;把甲的能力值的 2 個數字調換位置就是乙的能力值;甲乙兩人能力差是丙的能力值的 X 倍;乙的能力值是丙的 Y 倍。請你指出誰比你強應「從之」,誰比你弱應「改之」。

輸入格式:

輸入在一行中給出三個數,依次爲:M(你本身的能力值)、X 和 Y。三個數字均爲不超過 1000 的正整數。

輸出格式:

在一行中首先輸出甲的能力值,隨後依次輸出甲、乙、丙三人與你的關係:若是其比你強,輸出 Cong;平等則輸出 Ping;比你弱則輸出 Gai。其間以 1 個空格分隔,行首尾不得有多餘空格。

注意:若是解不惟一,則以甲的最大解爲準進行判斷;若是解不存在,則輸出 No Solution

輸入樣例 1:

48 3 7

輸出樣例 1:

48 Ping Cong Gai

輸入樣例 2:

48 11 6

輸出樣例 2:

No Solution

 

題解:

剛開始當作了是輸出M的值,一直不過。值得注意的是丙的值多是double類型的,但是我測試一下發現用int也能過經過。中間有一組數據被卡了,不知道是哪裏出錯了(-2)。

代碼:

#include<iostream>

using namespace std; 

void judge(int x, int y) {
    if (x == y) cout << "Ping";
    else if (x < y) cout << "Cong";
    else cout << "Gai";
}

int main() {
    int m, x, y;
    cin >> m >> x >> y;

    int p1, p2;
    double p3;
    for (int i = 99; i > 9; --i) {
        p1 = i;
        int t1, t2;
        t1 = i % 10;
        t2 = i / 10;
        p2 = t1 * 10 + t2;
        int sub = abs(p1 - p2);

        p3 = sub * 1.0 / x;
        if (p3 * y == p2) {
            cout << p1 << ' ';
            judge(m, p1);
            cout << ' ';
            judge(m, p2);
            cout << ' ';
            judge(m, p3);
            cout << endl;
            return 0;
        }
    }

    cout << "No Solution" << endl;

    return 0;
}

  

 

1089 狼人殺-簡單版 (20 分)

如下文字摘自《靈機一動·好玩的數學》:「狼人殺」遊戲分爲狼人、好人兩大陣營。在一局「狼人殺」遊戲中,1 號玩家說:「2 號是狼人」,2 號玩家說:「3 號是好人」,3 號玩家說:「4 號是狼人」,4 號玩家說:「5 號是好人」,5 號玩家說:「4 號是好人」。已知這 5 名玩家中有 2 人扮演狼人角色,有 2 人說的不是實話,有狼人撒謊但並非全部狼人都在撒謊。扮演狼人角色的是哪兩號玩家?

本題是這個問題的升級版:已知 N 名玩家中有 2 人扮演狼人角色,有 2 人說的不是實話,有狼人撒謊但並非全部狼人都在撒謊。要求你找出扮演狼人角色的是哪幾號玩家?

輸入格式:

輸入在第一行中給出一個正整數 N(5N100)。隨後 N 行,第 i 行給出第 i 號玩家說的話(1iN),即一個玩家編號,用正號表示好人,負號表示狼人。

輸出格式:

若是有解,在一行中按遞增順序輸出 2 個狼人的編號,其間以空格分隔,行首尾不得有多餘空格。若是解不惟一,則輸出最小序列解 —— 即對於兩個序列 A=a[1],...,a[M] 和 B=b[1],...,b[M],若存在 0k<M 使得 a[i]=b[i] (ik),且 a[k+1]<b[k+1],則稱序列 A 小於序列 B。若無解則輸出 No Solution

輸入樣例 1:

5
-2
+3
-4
+5
+4

輸出樣例 1:

1 4

輸入樣例 2:

6
+6
+3
+1
-5
-2
+4

輸出樣例 2(解不惟一):

1 5

輸入樣例 3:

5
-2
-3
-4
-5
-1

輸出樣例 3:

No Solution

 

題解:

枚舉全部可能的結果,在假設中的「好人」中若是還存在狼人,則不知足條件。根據題意「有狼人撒謊但並非全部狼人都在撒謊」可知有一個狼人說的是真話,另外個狼人說的是假話。說真話的狼人不可能這出另一個狼人來。說假話的狼人必定會陷害「好人」。

根據剛纔的假設,我寫的代碼只能經過兩組數據,不知道爲何會出錯。(-12)

 

代碼:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>

using namespace std;

bool cmp(pair<int, int> a, pair<int, int> b) {
    if (a.first == b.first) return a.second < b.second;
    else return a.first < b.first;
}

int main() {
    int n;
    string str;
    vector<string> lang;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> str;
        lang.push_back(str);
    }

    vector<pair<int, int>> ans;
    for (int i = 1; i <= n; ++i) {
        for (int j = i + 1; j <= n; ++j) {
            vector<int> temp(n+1, 0);
            string wolf1, wolf2;
            for (int k = 0; k < n; ++k) {
                char c = lang[k][0];
                string s(lang[k].begin()+1, lang[k].end());
                int num = stoi(s);
                if (k+1 == i) {
                    wolf1 = lang[k];
                    continue;
                } 
                if (k+1 == j) {
                    wolf2 = lang[k];
                    continue;
                }
                if (c == '-') temp[num]--;
                // else temp[num]--;
            }

            if (wolf1[0] == '-' && wolf2[0] == '-')
                continue;

            // 檢查除了假設的狼以外是否還存在其餘的狼
            // 若存在則說明這種假設不合理
            int flag = true;
            for (int k = 1; k <= n; ++k) {
                if (temp[k] < 0 && k != i && k != j) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                ans.push_back(make_pair(i, j));
            }
        }
    }
    if (!ans.empty()) {
        sort(ans.begin(), ans.end(), cmp);
        cout << ans[0].first << " " << ans[0].second << endl;
    } else {
        cout << "No Solution" << endl;
    }


    return 0;
}

  

 

大佬的解法:(https://blog.csdn.net/liuchuo/article/details/82560831)

分析:

每一個人說的數字保存在v數組中,i從1~n、j從i+1~n遍歷,分別假設i和j是狼人,a數組表示該人是狼人仍是好人,等於1表示是好人,等於-1表示是狼人。k從1~n分別判斷k所說的話是真是假,k說的話和真實狀況不一樣(即v[k] * a[abs(v[k])] < 0)則表示k在說謊,則將k放在lie數組中;遍歷完成後判斷lie數組,若是說謊人數等於2而且這兩個說謊的人一個是好人一個是狼人(即a[lie[0]] + a[lie[1]] == 0)表示知足題意,此時輸出i和j並return,不然最後的時候輸出No Solution~

code:

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main() {
    int n;
    cin >> n;
    vector<int> v(n+1);
    for (int i = 1; i <= n; i++) cin >> v[i];
    for (int i = 1; i <= n; i++) {
        for (int j = i + 1; j <= n; j++) {
            vector<int> lie, a(n + 1, 1);
            a[i] = a[j] = -1;
            for (int k = 1; k <= n; k++)
                if (v[k] * a[abs(v[k])] < 0) lie.push_back(k);
            if (lie.size() == 2 && a[lie[0]] + a[lie[1]] == 0) {
                cout << i << " " << j;
                return 0;
            }
        }
    }
    cout << "No Solution";
    return 0;
}

  

 

 

 

1090 危險品裝箱 (25 分)

集裝箱運輸貨物時,咱們必須特別當心,不能把不相容的貨物裝在一隻箱子裏。好比氧化劑絕對不能跟易燃液體同箱,不然很容易形成爆炸。

本題給定一張不相容物品的清單,須要你檢查每一張集裝箱貨品清單,判斷它們是否能裝在同一只箱子裏。

輸入格式:

輸入第一行給出兩個正整數:N (104​​) 是成對的不相容物品的對數;M (100) 是集裝箱貨品清單的單數。

隨後數據分兩大塊給出。第一塊有 N 行,每行給出一對不相容的物品。第二塊有 M 行,每行給出一箱貨物的清單,格式以下:

K G[1] G[2] ... G[K]

其中 K (1000) 是物品件數,G[i] 是物品的編號。簡單起見,每件物品用一個 5 位數的編號表明。兩個數字之間用空格分隔。

輸出格式:

對每箱貨物清單,判斷是否能夠安全運輸。若是沒有不相容物品,則在一行中輸出 Yes,不然輸出 No

輸入樣例:

6 3
20001 20002
20003 20004
20005 20006
20003 20001
20005 20004
20004 20006
4 00001 20004 00002 20003
5 98823 20002 20003 20006 10010
3 12345 67890 23333

輸出樣例:

No
Yes
Yes

 

題解:

記得當時考試的時候,弄了很長時間沒有弄出來,沒想到此次居然一遍就過了。感受正解應該是用並查集,可是本身菜寫不出了,因此就模擬了一下。

 

代碼:

#include<iostream>
#include<algorithm>
#include<map>
#include<set>

using namespace std;

int main() {
    int n, m;
    cin >> n >> m;

    map<int, set<int>> obj;
    for (int i = 0; i < n; ++i) {
        int x, y;
        cin >> x >> y;
        obj[x].insert(y);
    }    
    for (int i = 0; i < m; ++i) {
        int num, No;
        cin >> num;
        set<int> list;
        for (int j = 0; j < num; ++j) {
            cin >> No;
            list.insert(No);
        }
        bool flag = true;
        set<int>::iterator it = list.begin();
        for (; it != list.end(); ++it) {
            int root = *it;
            for (set<int>::iterator m_it = obj[root].begin(); m_it != obj[root].end(); ++m_it) {
                int leaf = *m_it;
                if (list.count(leaf)) {
                    cout << "No" << endl;
                    flag = false;
                    break;
                }
            }
            if (!flag) break;
        }
        if (flag) cout << "Yes" << endl;
    }

    return 0;
}

  

 

算下來,在本身能夠google的狀況下,我得了86分,雖然不是很滿意,但確實比上次參加比賽進步了很多。但願這週末的考試也能取得一個好成績吧。

相關文章
相關標籤/搜索