PAT 520 鑽石爭霸賽真題(2020-05-20)題解 #后三題


7-6 隨機輸一次 (20分)

現要求你編寫一個控制贏面的程序,根據對方的出招,給出對應的贏招。但是!為了不讓對方意識到你在控制結果,你需要隔 K 次輸一次,其中 K 是系統設定的隨機數。

輸入格式:

輸入首先在第一行給出正整數 N(≤10),隨后給出 N 個系統產生的不超過 10 的正隨機數 { K1,K2,⋯,KN },數字間以空格分隔。這意味着第 i(i=0,1,⋯,N−1)次輸局之后應該隔 Ki+1 次再讓下一個輸局。如果對方出招太多,則隨機數按順序循環使用。例如在樣例中,系統產生了 3 個隨機數 {2, 4, 1},則你需要:贏 2 次,輸 1 次;贏 4 次,輸 1 次;贏 1 次,輸 1 次;然后再次回到第 1 個隨機數,贏 2 次,輸 1 次。

之后每行給出對方的一次出招:“ChuiZi”代表“錘子”、“JianDao”代表“剪刀”、“Bu”代表“布”。“End”代表輸入結束,這一行不要作為出招處理。輸入保證對方至少出了一招。

輸出格式:

對每一個輸入的出招,按要求輸出贏或輸局的招式。每招占一行。

輸入樣例:

3 2 4 1
ChuiZi
JianDao
Bu
JianDao
Bu
ChuiZi
ChuiZi
ChuiZi
JianDao
Bu
JianDao
Bu
ChuiZi
End

輸出樣例:

Bu
ChuiZi
ChuiZi
ChuiZi
JianDao
Bu
Bu
JianDao
ChuiZi
ChuiZi
ChuiZi
JianDao
JianDao

思路

判斷flag是否等於a[cnt%N],這樣模擬的思路最簡單。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=1e6+10;

int a[100];

void win(string x) {
    if (x == "ChuiZi") cout << "Bu\n";
    else if (x == "JianDao") cout << "ChuiZi\n";
    else cout << "JianDao\n";
}

void lose(string x) {
    if (x == "ChuiZi") cout << "JianDao\n";
    else if (x == "JianDao") cout << "Bu\n";
    else cout << "ChuiZi\n";
}

int main() {
//     freopen("in.txt","r",stdin);

    int N;
    cin>>N;
    for (int i=0;i<N;i++) {
        cin>>a[i];
    }
    int flag=0,cnt=0;
    string s;
    while (cin>>s&&s!="End") {
        if (flag==a[cnt%N]) {
            lose(s);
            flag=0;
            cnt++;
        } else {
            win(s);
            flag++;
        }
    }
    return 0;
}

7-7 階乘的非零尾數 (20分)

7-7 階乘的非零尾數 (20分)

“求 N 階乘末尾的第一個非零數字”是一道常見的企業筆試題。這里我們略微做個變化,求 N 階乘末尾的第一個非零 K 位數,同時輸出末尾有多少個零。

輸入格式:

輸入給出一個不超過 107 的正整數 N 和要求輸出的位數 0<K<10。

輸出格式:

在一行中輸出 N 階乘末尾的第一個非零 K 位數(注意前導零也要輸出)、以及末尾 0 的個數,其間以 1 個空格分隔。

輸入樣例:

18 5

輸出樣例:

05728 3

思路

先把所有的5和2剔除,然后把漏掉的5 或 2再乘上去。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const long long MAXN = 1e6 + 10;

int main()
{
    // freopen("in.txt", "r", stdin);

    long long N, K;
    cin >> N >> K;
    long long base = 1;
    for (long long i = 0; i < K; i++)
    {
        base *= 10;
    }
    long long cnt2 = 0, cnt5 = 0, num = 1;
    for (long long i = 1; i <= N; i++)
    {
        long long m = i;
        while (m % 5 == 0) { m /= 5; cnt5++; }
        while (m % 2 == 0) { m/=2; cnt2++; }
        num*=m;
        num%=base;
    }
    long long cnt=min(cnt2,cnt5);
    for (long long i=0;i<cnt2-cnt;i++) { num=2ll*num%base; }
    for (long long i=0;i<cnt5-cnt;i++) { num=5ll*num%base; }
    long long tmp=num,bits=0;
    while (tmp) {
        bits++;
        tmp/=10;
    }
    for (long long i=0;i<K-bits;i++) { cout<<"0"; }
    cout<<num<<" "<<cnt<<endl;
    return 0;
}

7-8 三足鼎立 (25分)

當三個國家中的任何兩國實力之和都大於第三國的時候,這三個國家互相結盟就呈“三足鼎立”之勢,這種狀態是最穩定的。

現已知本國的實力值,又給出 n 個其他國家的實力值。我們需要從這 n 個國家中找 2 個結盟,以成三足鼎立。有多少種選擇呢?

輸入格式:

輸入首先在第一行給出 2 個正整數 n(2≤n≤105)和 P(≤109),分別為其他國家的個數、以及本國的實力值。隨后一行給出 n 個正整數,表示n 個其他國家的實力值。每個數值不超過 109,數字間以空格分隔。

輸出格式:

在一行中輸出本國結盟選擇的個數。

輸入樣例:

7 30
42 16 2 51 92 27 35

輸出樣例:

9

樣例解釋:

能聯合的另外 2 個國家的 9 種選擇分別為:

{16, 27}, {16, 35}, {16, 42}, {27, 35}, {27, 42}, {27, 51}, {35, 42}, {35, 51}, {42, 51}。

思路

  • 如果p不是最大,則滿足條件的是小於a[i]+p的數
  • 如果p是最大 , 則滿足條件的是大於p-a[i]的數

用lower_bound是為了多計入一位,這樣避免x==y,x-y=0。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN=1e5+10;

long long a[MAXN];
int main() {
//     freopen("in.txt","r",stdin);

    long long N,P;
    cin>>N>>P;
    for (int i=0;i<N;i++) {
        cin>>a[i];
    }
    long long ans=0;
    sort(a,a+N);
    for (int i=0;i<N;i++) {
        long long x=lower_bound(a+i+1,a+N,a[i]+P)-a;
        long long y=upper_bound(a+i+1,a+N,P-a[i])-a;
        ans+=max(0ll,x-y);
    }
    cout<<ans<<endl;
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM