【PTA】PAT(上級)演習 1011-1014

1011 ワールドカップの賭け

2010 FIFA ワールドカップが開催され、世界中のサッカーファンは、南アフリカでワールドカップのトロフィーを目指して最高のチームの最高の選手たちが戦いを繰り広げる様子にますます興奮していました。同様に、サッカー賭博ファンは、ワールドカップのあらゆる種類の賭けをして、自分のお金を賭けていました。

中国のサッカー宝くじは「トリプルウィニング」ゲームを提供しました。勝利のルールは簡単です。まず、いずれかのゲームを 3 つ選択します。次に、選択した各ゲームについて、3 つの可能な結果の 1 つに賭けます。すなわち、勝ちは W、引き分けは T、負けは L です。各結果には奇数が割り当てられました。勝者のオッズは、3 つのオッズの積に 65% を掛けたものになります。

たとえば、3 試合のオッズは次のようになります。

WTL
1.1 2.5 1.7
1.2 3.1 1.6
4.1 1.2 1.1
最大の利益を得るには、3 番目のゲームには W、2 番目のゲームには T、そして 1 番目のゲームには T を購入する必要があります。各賭けに 2 元かかる場合、最大利益は (4.1×3.1×2.5×65%−1)×2 = 39.31 元になります (小数点第 2 位までの精度)。

入力仕様:
各入力ファイルには 1 つのテスト ケースが含まれます。各ケースには 3 つのゲームの賭け情報が含まれています。各ゲームは、W、T、L に対応する 3 つの異なるオッズを持つラインを占めます。

出力仕様:
各テスト ケースについて、各ゲームの最良の賭けと、小数点第 2 位までの正確な最大利益を 1 行で出力します。文字と数字はスペース 1 つで区切る必要があります。

サンプル入力:

1.1 2.5 1.7
1.2 3.1
1.6 4.1 1.2 1.1

サンプル出力:

TTW 39.31

翻訳:

ワールドカップのギャンブルは3試合あり、それぞれの試合にW(勝ち)、T(引き分け)、L(負け)のオッズを与え、最大の利益を追求します。
このトピックでは、2 元を賭けるたびに、各ゲームで最もオッズが高い 3 つの数字 a、b、c を選択し、(a * b * c * 0.65 - 1) に基づいて最大利益を計算する必要があると述べています。 ※2.

コード: (要素の検索)

#include<iostream>
#include<iomanip>
using namespace std;
int main(){
    
    
    char a[4]={
    
    "WTL"};
    double result = 1.0;//三个最大赔率的乘积
    int index;//记录某一行中最大赔率的下标
    
    for(int i=0; i<3; i++){
    
    //3列
        double max=0.0;
        for(int j=0; j<3; j++){
    
    //3行
            double temp;
            cin>>temp;//输入赔率
            if(temp >= max){
    
    //判断是否是这一行中最大的值,如果是就替换max
                max = temp;
                index = j;//记录是这一行的第几个赔率,方便等一下输出TWL
            }
        }
        result *= max;
        cout<<a[index]<<" ";
    }
    cout<< setiosflags(ios::fixed)<<setprecision(2)<<(result * 0.65 -1) *2;
}

1012 ザ・ベストランク

CS 専攻の 1 年生の成績を評価するために、C - C プログラミング言語、M - 数学 (微積分または線形代数)、および E - 英語の 3 つのコースのみの成績を考慮します。その一方で、私たちは学生の最高順位を重視して学生を奨励します。つまり、3 つのコースと平均成績に関する 4 つのランクのうち、各学生の最高の順位を印刷します。

たとえば、C、M、E、A の成績 (4 人の生徒の平均) は次のように与えられます。

学生ID CMEA
310101 98 85 88 90
310102 70 95 88 84
310103 82 87 94 88
310104 91 91 91 91

すると、1 番目の生徒が C プログラミング言語で最も良い成績を収めたため、全生徒の最高順位は 1 位となり、2 番目の生徒は数学、3 番目の生徒は英語、そして最後の生徒が平均でした。

入力仕様:
各入力ファイルには 1 つのテスト ケースが含まれます。各ケースは、2 つの数値 N と M (≤2000) を含む行で始まります。これらは、それぞれ生徒の総数とランクをチェックする生徒の数です。次に N 行が続き、それぞれに 6 桁の文字列である学生 ID が含まれ、その後にその学生の 3 つの整数成績 ([0, 100] の範囲) が C、M、E の順で続きます。は M 行で、それぞれに学生 ID が含まれます。

出力仕様:
M 人の生徒ごとに、その生徒の最高のランクと、対応するランクの記号をスペースで区切って 1 行に出力します。

ランク付け方法の優先順位は、A > C > M > E の順に並べられます。したがって、生徒が同じ最高のランクを取得する方法が 2 つ以上ある場合は、優先度が最も高い方法を出力します。

学生が採点リストに載っていない場合は、単純に「N/A」と出力します。

サンプル入力:

5 6
310101 98 85 88
310102 70 95 88
310103 82 87 94
310104 91 91 91
310105 85 90 90
310101
310102
310103
310104
310105
99 9999

サンプル出力:

1 C
1 M
1 E
1 A
3 A
該当なし

翻訳:

M 人の候補者があり、N 人の候補者に成績があることが知られています。
入力サンプルの最初の N 行は次のとおりです。

学籍番号の科目Cの成績 科目Mの成績 科目Eの成績

最後の M 行は、受験者全員の学生番号です。

必要な出力: 各候補者と対応する主題の最高のランキング。ランキングが同じ場合は、A(合計点)>C>M>Eの順に出力し、候補者にスコアがない場合はN/Aを出力します。

コード: (ソート)

#include<iostream>
#include<algorithm>
using namespace std;

//看到学生学号成绩联想到结构体
struct node{
    
    
    int id,best;
    int score[4], rank[4];
}stu[2005];

int flag=-1,exist[1000000];//exist:当前考生的学号是否存在

//比较分数排序
bool cmp1(node a, node b){
    
    
    return a.score[flag] > b.score[flag];
}

int main(){
    
    
    int N , M , id;
    cin >> N >> M;
    
    for(int i=0;i<N ;i++){
    
    
        cin>>stu[i].id>>stu[i].score[1]>>stu[i].score[2]>>stu[i].score[3];
        
        //计算平均分(加0.5后取整,四舍五入)
        stu[i].score[0] = (stu[i].score[1]+stu[i].score[2]+stu[i].score[3])/3.0+0.5;
    }
    
    for(flag=0; flag<=3; flag++){
    
    //科目
        //按照分数排序
        sort(stu, stu+N, cmp1);
        
        //因为前面排好序了,所以现在数组里面第一个学生的排名就是1
        stu[0].rank[flag] = 1;
        for(int i=1; i<N ;i++){
    
     //学生
            stu[i].rank[flag] = i+1;//按序给排名
            //分数相同的情况
            if(stu[i].score[flag]==stu[i-1].score[flag])
                stu[i].rank[flag] = stu[i-1].rank[flag];
        }
    }
    
    for(int i=0; i<N;i++){
    
    
        exist[stu[i].id] = i+1;//已存在的学号按顺序记录下来
        stu[i].best = 0;
        int min = stu[i].rank[0];
        //找出每个学生最好的排名
        for(int j = 1;j<=3; j++){
    
    
            if(stu[i].rank[j] < min){
    
    
                min = stu[i].rank[j];
                stu[i].best = j;
            }
        }
    }
    
    char c[5] = {
    
    'A', 'C', 'M', 'E'};
    for(int i=0 ; i<M ; i++){
    
    
        cin >> id;//输入学号,去找对应的排名
        int temp = exist[id];
        if(temp){
    
    
            int best = stu[temp-1].best;
            cout << stu[temp-1].rank[best] <<" "<< c[best]<< endl;
        }else{
    
    
            cout<<"N/A"<<endl;
        }
    }
    return 0;
}

1013 都市をめぐる戦い

戦争においては、すべての都市が高速道路で結ばれることが極めて重要です。都市が敵に占領されると、その都市に向かう、またはその都市に向かうすべての高速道路が閉鎖されます。残りの都市を接続し続けるために他の高速道路を修復する必要があるかどうかをすぐに知る必要があります。残りの高速道路がすべてマークされている都市の地図を考えると、修理が必要な高速道路の数をすぐに伝える必要があります。

入力仕様:
各入力ファイルには 1 つのテスト ケースが含まれます。各ケースは、3 つの数値 N (<1000)、M、K を含む行で始まります。これらはそれぞれ、都市の総数、残りの高速道路の数、チェック対象の都市の数です。次に M 行が続き、それぞれが高速道路を 2 つの整数で表します。これらの整数は、高速道路が接続する都市の番号です。都市には 1 から N までの番号が付けられています。最後に、関心のある都市を表す K の数字を含む行があります。

出力仕様:
K 都市ごとに、その都市が失われた場合に修復する必要がある高速道路の数を 1 行で出力します。

サンプル入力:

3 2 3
1 2
1 3
1 2 3

サンプル出力:

1
0
0

翻訳:

戦争では、すべての都市を高速道路で結ぶことが重要です。都市が敵に占領されると、その都市に通じる道路はすべて閉鎖されます。他の都市との接続を維持するために他の高速道路を修正する必要があるかどうかをすぐに知る必要があります。残りのすべての高速道路が地図上にマークされているので、修正する必要がある高速道路の数をすぐに伝える必要があります。

入力サンプル:
各行には、都市の総数、高速道路の残りの数、確認する都市の数を表す N、M、K の 3 つの数字が含まれています。
次は M 行で、各行は 2 つの整数で高速道路を表しており、この 2 つの整数は高速道路で接続されている都市の番号です。
都市には 1 から n までの番号が付けられており、最後の行には関心のある都市を表す K 個の数字が含まれています。

出力仕様:
K 都市ごとに、都市が失われた場合に修復する必要がある道路の数を 1 行で出力します。

コード: (グラフ理論)

#include<iostream>
#include<algorithm> // std::fill
using namespace std;
int n;
int v[1010][1010];
bool visit[1010];

//深度遍历
void dfs(int node){
    
    
    visit[node] = true;//将能经过的城市全部标记起来
    for(int i =1;i<=n;i++){
    
    
        if(visit[i] == false && v[node][i] ==1){
    
    
            dfs(i);
        }
    }
}

int main(){
    
    
    int m,k,a,b;
    cin>>n>>m>>k;
    for(int i = 0; i<m; i++){
    
    
        cin>>a>>b;
        v[a][b]=v[b][a]=1;//无向图
    }
    for(int i=0;i<k;i++){
    
    
        fill(visit, visit+1010, false);//填充visit[]
        cin>>a;
        int cnt=0;
        visit[a] = true;//出现的城市都标true
        for(int j =1;j<=n;j++){
    
    
            if(visit[j] == false){
    
    //没有经过的城市
                dfs(j);
                cnt++;//要修复铁路+1
            }
        }
        cout<<cnt-1<<endl;
    }
    
    return 0;
}

1014 列に並んで待っています

銀行がサービスのために N 個の窓口を開いていると仮定します。窓口の前に黄色い線があり、待合室が2つに分かれています。お客様が列に並んで待つ際のルールは次のとおりです。

各窓の前の黄色の線の内側のスペースは、M 人の顧客の列を収容するのに十分です。したがって、N 列すべてが満席の場合、(NM+1) 番目の列以降 (NM+1 列を含む) のすべての顧客は、黄色の列の後ろに並んで待たなければなりません。
各顧客は、黄色の線を越えるときに、最短の列で待つことになります。同じ長さの線が 2 つ以上ある場合、顧客は常に最小番号のウィンドウを選択します。
顧客 i の取引が処理されるまでに T i 分かかります。
最初の N 人の顧客は午前 8 時にサービスを受けると想定されます。
各顧客の処理時間を考慮すると、顧客が業務を完了した正確な時間を伝える必要があります。

たとえば、銀行に 2 つの窓口があり、各窓口に 2 人の顧客が黄色の線の内側で待っているとします。5 人の顧客が待機しており、取引に 1 分、2 分、6 分、4 分、3 分かかります。
ここに画像の説明を挿入

入力仕様:
各入力ファイルには 1 つのテスト ケースが含まれます。各ケースは、4 つの正の整数を含む行で始まります: N (≤20、ウィンドウの数)、M (≤10、黄色の線内の各行の最大容量)、K (≤1000、顧客の数)、および Q (≤1000、顧客クエリの数)。

次の行には K 個の正の整数が含まれており、これは K 人の顧客の処理時間です。

最後の行には Q 個の正の整数が含まれており、取引を完了できる時間を尋ねている顧客を表します。顧客には 1 から K までの番号が付けられます。

出力仕様:
Q の顧客ごとに、トランザクションが終了した時刻を HH:MM の形式で 1 ​​行に出力します。HH は [08, 17]、MM は [00, 59] です。銀行は毎日 17:00 以降に閉まるため、17:00 までに対応できない顧客については、代わりに Sorry を出力する必要があることに注意してください。

サンプル入力:

2 2 7 5
1 2 6 4 3 534 2
3 4 5 6 7

サンプル出力:

08:07
08:06
08:10
17:00
ごめんなさい

翻訳:

n 個の窓口があり、各窓口には m 人が並ぶことができ、対応が必要な人数は k 人で、各人に対応する必要がある時間が与えられています。サービスは朝 8 時に始まります
。満員ではないウィンドウです。キューに参加してください。そうでない場合は、黄色の線になります。外でお待ちください。17:00 を過ぎてもサービスが開始されていない場合は、サービスが停止されます。すでに開始されている場合は、サービスが終了するまでお待ちください。
個人サービスの時間を q に尋ねてください

コード: (キュー)

#include<iostream>
#include<queue>
#include<vector>
#include<iomanip>
using namespace std;
//结构体:包含队首的人出队时间队尾poptime,队尾的人的结束时间endtime
struct node{
    
    
    int poptime, endtime;
    queue<int> q;
};

int main(){
    
    
    int n,m,k,q,index=1;
    cin>>n>>m>>k>>q; //n个窗口,每个窗口最多有m个客户,总客户k人,求q人服务时间
    vector<int> time(k+1), result(k+1);//result是所求q人要的服务时间
    for(int i=1;i<=k;i++){
    
    
        cin>>time[i];
    }
    vector<node> window(n+1);//窗口服务的客户
    vector<bool> sorry(k+1, false);//不服务的客户
    
    //对于前面的n*m个人来说,依次排队
    for(int i=1;i<=m;i++){
    
    
        for(int j=1;j<=n;j++){
    
    
            if(index <=k ){
    
    
                window[j].q.push(time[index]);
                if(window[j].endtime >= 540)//超过17:00,不服务
                    sorry[index] = true;
                window[j].endtime += time[index];//多服务一个人,结束时间就增加多一点
                if(i==1)//如果只服务一个人
                    window[j].poptime = window[j].endtime;
                result[index] = window[j].endtime;
                index++;
            }
        }
    }
    
    //n*m之后的人,选择poptime最小的队伍,入队,同时让队伍第一个人出队
    while(index <= k){
    
    
        int tempmin = window[1].poptime, tempwindow = 1;
        //选择poptime最小的队伍
        for(int i=2;i<=n;i++){
    
    
            if(window[i].poptime < tempmin){
    
    
                tempwindow = i;
                tempmin = window[i].poptime;
            }
        }
        window[tempwindow].q.pop(); //队伍第一个人出队
        window[tempwindow].q.push(time[index]); //新人入队
        window[tempwindow].poptime += window[tempwindow].q.front(); //现在队列第一个人的出队时间
        if(window[tempwindow].endtime >= 540 )//超过17:00
            sorry[index] = true;
        window[tempwindow].endtime += time[index];
        result[index] = window[tempwindow].endtime;
        index++;
    }
    for(int i=1; i<=q; i++){
    
    
        int query, minute;
        cin>>query;
        minute = result[query];
        
        if(sorry[query] == true){
    
    
            cout<<"Sorry"<<endl;
        } else {
    
    
            //转换成小时的形式输出
            if((minute+480)/60<10) cout<<0;
            cout<<(minute+480)/60;
            cout<<":";
            if((minute+480)%60<10) cout<<0;
            cout<<(minute+480)%60<<endl;
        }
    }
}

終わり

おすすめ

転載: blog.csdn.net/qq_51669241/article/details/125708468