1. 程式人生 > >PAT乙級(C++)1011-1015

PAT乙級(C++)1011-1015

1011. A+B和C

給定區間[-231, 231]內的3個整數A、B和C,請判斷A+B是否大於C。

輸入格式:
輸入第1行給出正整數T(<=10),是測試用例的個數。隨後給出T組測試用例,每組佔一行,順序給出A、B和C。整數間以空格分隔。

輸出格式:
對每組測試用例,在一行中輸出“Case #X: true”如果A+B>C,否則輸出“Case #X: false”,其中X是測試用例的編號(從1開始)。

輸入樣例:
4
1 2 3
2 3 4
2147483647 0 2147483646
0 -2147483648 -2147483647
輸出樣例:
Case #1: false
Case #2: true
Case #3: true
Case #4: false

注意1:A、B、C的數值可能超出int的表示範圍,用long就行啦。

#include <iostream>
using namespace std;
int main(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        long a=0,b=0,c=0;
        cin>>a>>b>>c;   
        if(a+b>c)
            cout<<"Case #"<<i+1<<": true\n"
; else cout<<"Case #"<<i+1<<": false\n"; } return 0; }

1012. 數字分類

給定一系列正整數,請按要求對數字進行分類,並輸出以下5個數字:

A1 = 能被5整除的數字中所有偶數的和;
A2 = 將被5除後餘1的數字按給出順序進行交錯求和,即計算n1-n2+n3-n4…;
A3 = 被5除後餘2的數字的個數;
A4 = 被5除後餘3的數字的平均數,精確到小數點後1位;
A5 = 被5除後餘4的數字中最大數字。

輸入格式:
每個輸入包含1個測試用例。每個測試用例先給出一個不超過1000的正整數N,隨後給出N個不超過1000的待分類的正整數。數字間以空格分隔。

輸出格式:
對給定的N個正整數,按題目要求計算A1~A5並在一行中順序輸出。數字間以空格分隔,但行末不得有多餘空格。

若其中某一類數字不存在,則在相應位置輸出“N”。

輸入樣例1:
13 1 2 3 4 5 6 7 8 9 10 20 16 18
輸出樣例1:
30 11 2 9.7 9

輸入樣例2:
8 1 2 4 5 6 7 9 16
輸出樣例2:
N 11 2 N 9

#include<iostream>  
using namespace std; 

int main(){
    int n;  
    cin>>n;  
    int *nums = new int[n];
    for(int i=0;i<n;i++)  
        cin>>nums[i];   
    int A1=0,A2=0,A3=0,A5=0;
    float A4=0;
    bool A2flag = true;
    int A1Num=0,A2Num=0,A3Num=0,A4Num=0,A5Num=0;
    for(int i=0;i<n;i++){
        int test = nums[i];
        switch(test%5){
        case 0:
            if(test%2==0){
                A1=A1+test;
                A1Num++;
            }               
            break;      
        case 1:
            if(A2flag){
                A2 = A2+test;   
            }
            else{
                A2 = A2-test;
            }
            A2flag = !A2flag;
            A2Num++;
            break;  
        case 2:
            A3++;
            A3Num++;
            break;      
        case 3:
            A4 = A4+test;
            A4Num++;
            break;      
        case 4:
            if(test>A5){
                A5=test;
            }
            A5Num++;
            break;
        }
    }
    if(A1Num==0)
        cout<<"N"<<" ";
    else
        cout<<A1<<" ";  
    if(A2Num==0)
        cout<<"N"<<" ";
    else
        cout<<A2<<" ";
    if(A3Num==0)
        cout<<"N"<<" ";
    else
        cout<<A3<<" ";
    if(A4Num==0)
        cout<<"N"<<" ";
    else{ 
        int temp = (A4/A4Num+0.05)*10;
        A4 =(float) temp/10; 
        cout<<A4<<" ";
    }   
    if(A5Num==0)
        cout<<"N"<<"";
    else
        cout<<A5<<"";
    return 0;
}

1013. 數素數

令Pi表示第i個素數。現任給兩個正整數M <= N <= 104,請輸出PM到PN的所有素數。

輸入格式:
輸入在一行中給出M和N,其間以空格分隔。

輸出格式:
輸出從PM到PN的所有素數,每10個數字佔1行,其間以空格分隔,但行末不得有多餘空格。

輸入樣例:
5 27
輸出樣例:
11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103

#include<iostream>  
#include <math.h> 
using namespace std; 
bool isPrime(int i){
    if(i==1)
        return false;
    if(i==2)
        return true;
    for(int j=2;j<=sqrt(i)+1;j++){
        if(i%j==0)
            return false;
    }
    return true;
} 
int main(){
    int num;  
    int m,n;
    cin>>m;
    cin>>n;  
    int current = 0,index=0,tens=0;
    while(current<n){
        index++;
        if(isPrime(index)){
            current++;  
        if(current>=m){
                tens++;
                if(current==n)
                    cout<<index<<"";
                else if(tens==10){
                    cout<<index<<"\n";
                    tens=0;
                }
                else
                    cout<<index<<" ";   
            }
        } 
    } 
}

1014. 福爾摩斯的約會

大偵探福爾摩斯接到一張奇怪的字條:“我們約會吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm”。大偵探很快就明白了,字條上奇怪的亂碼實際上就是約會的時間“星期四 14:04”,因為前面兩字串中第1對相同的大寫英文字母(大小寫有區分)是第4個字母’D’,代表星期四;第2對相同的字元是’E’,那是第5個英文字母,代表一天裡的第14個鐘頭(於是一天的0點到23點由數字0到9、以及大寫字母A到N表示);後面兩字串第1對相同的英文字母’s’出現在第4個位置(從0開始計數)上,代表第4分鐘。現給定兩對字串,請幫助福爾摩斯解碼得到約會的時間。

輸入格式:
輸入在4行中分別給出4個非空、不包含空格、且長度不超過60的字串。

輸出格式:
在一行中輸出約會的時間,格式為“DAY HH:MM”,其中“DAY”是某星期的3字元縮寫,即MON表示星期一,TUE表示星期二,WED表示星期三,THU表示星期四,FRI表示星期五,SAT表示星期六,SUN表示星期日。題目輸入保證每個測試存在唯一解。

輸入樣例:
3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm
輸出樣例:
THU 14:04

注意1: 大坑,題中所說的字母相同,是指長得一樣,位置還要一樣。

#include <stdio.h>    
#include <iostream>       
using namespace std;  
int main(){
    string s1,s2,s3,s4;
    cin>>s1>>s2>>s3>>s4;
    bool firstSame = true;
    string date[] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};
    for(int i=0;i<s1.length();i++){
        char c = s1[i];
        if(c==s2[i])
            if(firstSame){
                if(c>='A' && c<='G'){
                    firstSame = false;
                    cout<<date[c-'A']<<" ";
                }
            }
            else{
                if(c>='0' && c<='9'){
                    cout<<0<<c<<":";
                    break;
                }
                else if(c>='A' && c<='N'){
                    cout<<c-'A'+10<<":";
                    break;
                }
            }       
    } 
    for(int i=0;i<s3.length();i++){
        char c = s3[i];
        if(c==s4[i])
            if((c>='A' && c<='Z')||(c>='a' && c<='z')){
                if(i<10)
                    cout<<0<<i;
                else
                    cout<<i;
                break;
            }
    }   
    return 0;
} 

1015. 德才論

宋代史學家司馬光在《資治通鑑》中有一段著名的“德才論”:“是故才德全盡謂之聖人,才德兼亡謂之愚人,德勝才謂之君子,才勝德謂之小人。凡取人之術,苟不得聖人,君子而與之,與其得小人,不若得愚人。”

現給出一批考生的德才分數,請根據司馬光的理論給出錄取排名。

輸入格式:
輸入第1行給出3個正整數,分別為:N(<=105),即考生總數;L(>=60),為錄取最低分數線,即德分和才分均不低於L的考生才有資格被考慮錄取;H(<100),為優先錄取線——德分和才分均不低於此線的被定義為“才德全盡”,此類考生按德才總分從高到低排序;才分不到但德分到線的一類考生屬於“德勝才”,也按總分排序,但排在第一類考生之後;德才分均低於H,但是德分不低於才分的考生屬於“才德兼亡”但尚有“德勝才”者,按總分排序,但排在第二類考生之後;其他達到最低線L的考生也按總分排序,但排在第三類考生之後。

隨後N行,每行給出一位考生的資訊,包括:准考證號、德分、才分,其中准考證號為8位整數,德才分為區間[0, 100]內的整數。數字間以空格分隔。

輸出格式:
輸出第1行首先給出達到最低分數線的考生人數M,隨後M行,每行按照輸入格式輸出一位考生的資訊,考生按輸入中說明的規則從高到低排序。當某類考生中有多人總分相同時,按其德分降序排列;若德分也並列,則按准考證號的升序輸出。

輸入樣例:
14 60 80
10000001 64 90
10000002 90 60
10000011 85 80
10000003 85 80
10000004 80 85
10000005 82 77
10000006 83 76
10000007 90 78
10000008 75 79
10000009 59 90
10000010 88 45
10000012 80 100
10000013 90 99
10000014 66 60
輸出樣例:
12
10000013 90 99
10000012 80 100
10000003 85 80
10000011 85 80
10000004 80 85
10000007 90 78
10000006 83 76
10000005 82 77
10000002 90 60
10000014 66 60
10000008 75 79
10000001 64 90

思路: 題目中將學生劃分為五類,前四類將學生人數按總分內部排名。因為不想每個類都進行一次排名,索性給四類學生的分數添上附加分,使得第一類的分永遠高出第二類,這樣就可以統一進行排名,只需進行一次。
附加分的計算:前一類最低分+rank>後一類最高分。
注意: 使用時間複雜度為n2的排序演算法貌似會超時。(QwQ凡人如我)最終用了標頭檔案algorithm中的排序演算法。
STL的sort()演算法,資料量大時採用Quick Sort,分段遞迴排序,一旦分段後的資料量小於某個門檻,為避免Quick Sort的遞迴呼叫帶來過大的額外負荷,就改用Insertion Sort。如果遞迴層次過深,還會改用Heap Sort。

#include <stdio.h>
#include <algorithm>
using namespace std; 
struct student{
    int id;
    int d;
    int c;
    int sum;
};
int cmp(student i,student j){
    if(i.sum!=j.sum)
        return i.sum>j.sum;
    else if(i.d!=j.d)
        return i.d>j.d;
    else
        return i.id<j.id;
}

int main(){
    int N,L,H;
    scanf("%d%d%d", &N, &L, &H);  
    int rank3 = 2*H;
    int rank2 = rank3 + H;
    int rank1 = rank2 + 100;

    student *students = new student[N];

    int pass=0,x,y,z,sum;
    for(int j=0;j<N;j++){
        scanf("%d%d%d", &x, &y, &z);

        if(y>=L && z>=L){
            if(y>=H && z>=H){
                sum = y + z + rank1; 
            }
            else if(y>=H && z<H){
                sum = y + z + rank2; 
            }
            else if(y<H && y>=z){
                sum = y + z + rank3; 
            }
            else{
                sum = y + z; 
            }
            students[pass].id= x;
            students[pass].d= y;
            students[pass].c = z;
            students[pass].sum= sum;
            pass++;
        }
    }
    printf("%d\n",pass);
    if(pass>1){
        sort(students,students+pass,cmp);
    }
    for(int i=0;i<pass;i++){
        printf("%d %d %d\n", students[i].id, students[i].d, students[i].c);  
    }
    return 0;
}