1. 程式人生 > >PTA - No.9 - 12道題總結

PTA - No.9 - 12道題總結

這周的程式設計題還是有點難度的,而且程式碼有的比較長不好截圖分享到群相簿,發文本又太沒意思,就直接一起記錄在一個部落格裡好了:(所有的程式都只需要 #include <stdio.h> 所以不每個都寫了

7-1 查詢整數 (10 分)

本題要求從輸入的N個整數中查詢給定的X。如果找到,輸出X的位置(從0開始數);如果沒有找到,輸出“Not Found”。

輸入格式:

輸入在第一行中給出兩個正整數N(≤20)和X,第二行給出N個整數。數字均不超過長整型,其間以空格分隔。

輸出格式:

在一行中輸出X的位置,或者“Not Found”。

輸入樣例1: 5 7 

                     3 5 7 1 9

輸出樣例1: 2

輸入樣例2: 5 7

                     3 5 8 1 9

輸出樣例2: Not Found

int main()
{
    int N, X, t, i;
    scanf("%d%d", &N, &X);
    for(i = 0; i < N; i++)
    {
        scanf("%d", &t);
        if(t == X)
        {
            printf("%d\n", i);
            break;
        }
    }
    if(i == N)    printf("Not Found\n");
    return 0;
}

7-2 將陣列中的數逆序存放 (20 分) 

將給定的n個整數存入陣列中,將陣列中的這n個數逆序存放,再按順序輸出陣列中的元素。

輸入格式:

輸入在第一行中給出一個正整數n(1≤n≤10)。第二行輸入n個整數,用空格分開。

輸出格式:

在一行中輸出這n個整數的處理結果,相鄰數字中間用一個空格分開,行末不得有多餘空格。

輸入樣例: 4

                10 8 1 2

輸出樣例: 2 1 8 10

int main()
{
    int n, a[10];
    scanf("%d", &n);
    for(int i = 0; i < n; i++)      scanf("%d", &a[i]);
    for(int i = n - 1; i > 0; i--)  printf("%d ", a[i]);
    printf("%d\n", a[0]);       // 行末不得有多餘空格
    return 0;
}

7-3 選擇法排序 (20 分)

本題要求將給定的n個整數從大到小排序後輸出。

輸入格式:

輸入第一行給出一個不超過10的正整數n。第二行給出n個整數,其間以空格分隔。

輸出格式:

在一行中輸出從大到小有序的數列,相鄰數字間有一個空格,行末不得有多餘空格。

輸入樣例:4

                  5 1 7 6

輸出樣例:7 6 5 1

int main()
{
    int n, a[10];
    scanf("%d", &n);
    for(int i = 0; i < n; i++)    scanf("%d", &a[i]); // 先全讀進來
    for(int i = 0; i < n - 1; i++)      // 每次選一個最小的和有序列後一位交換
    {
        int minV = a[i], minIdx = i;      // 最小值,最小值位置
        for(int j = i + 1; j < n; j++)
            if(a[j] < minV)
            {
                minV = a[j];
                minIdx = j;
            }
        if(minIdx != i)
        {
            int tmp = a[i];
            a[i] = a[minIdx];
            a[minIdx] = tmp;
        }
    }
    for(int i = n - 1; i > 0; i--)
        printf("%d ", a[i]);
    printf("%d\n", a[0]);   // 行末不得有多餘空格
    return 0;
}

7-4 交換最小值和最大值 (15 分)

先將輸入的一系列整數中的最小值與第一個數交換,然後將最大值與最後一個數交換,最後輸出交換後的序列。

注意:題目保證最大和最小值都是唯一的。

輸入格式:

輸入在第一行中給出一個正整數N(≤10),第二行給出N個整數,數字間以空格分隔。

輸出格式:

在一行中順序輸出交換後的序列,每個整數後跟一個空格。

輸入樣例:5

                  8 2 5 1 4

輸出樣例:1 2 5 4 8

int main()
{
    int n, a[10];
    scanf("%d", &n);
    for (int i = 0; i < n; i++)		scanf("%d", &a[i]);
    int max = -1, maxi = -1, min = 2147483647, mini = -1; // INT_MAX
    for(int i = 0; i < n; i++)
        if(a[i] < min)
        {
            min = a[i];
            mini = i;
        }
    a[mini] = a[0];
    a[0] = min;
    for(int i = 0; i < n; i++)  // 必須重新計算,因為交換min之後,最大值位置可能變了
        if(a[i] > max)
        {
            max = a[i];
            maxi = i;
        }
    a[maxi] = a[n - 1];
    a[n - 1] = max;
    for(int i = 0; i < n; i++)
        printf("%d ", a[i]);
    return 0;
}

7-5 簡化的插入排序 (15 分)

本題要求編寫程式,將一個給定的整數插到原本有序的整數序列中,使結果序列仍然有序。

輸入格式:

輸入在第一行先給出非負整數N(<10);第二行給出N個從小到大排好順序的整數;第三行給出一個整數X。

輸出格式:

在一行內輸出將X插入後仍然從小到大有序的整數序列,每個數字後面有一個空格。

輸入樣例:

5

1 2 4 5 7

3

輸出樣例:

1 2 3 4 5 7

int main()
{
    int N, a[10], X;
    scanf("%d", &N);
    for(int i = 0; i < N; i++)
        scanf("%d", &a[i]);
    scanf("%d", &X);
    int i;
    for(i = 0; i < N; i++)
        if(a[i] > X)
        {
            for(int j = N; j > i; j--)
                a[j] = a[j - 1];
            a[i] = X;
            break;
        }
    if(i == N)                  // 都比X小
        a[N] = X;
    for(int i = 0; i <= N; i++)
        printf("%d ", a[i]);    // 每個數字後面有一個空格
    return 0;
}

7-6 求一批整數中出現最多的個位數字 (20 分)

給定一批整數,分析每個整數的每一位數字,求出現次數最多的個位數字。例如給定3個整數1234、2345、3456,其中出現最多次數的數字是3和4,均出現了3次。

輸入格式:

輸入在第1行中給出正整數N(≤1000),在第二行中給出N個不超過整型範圍的非負整數,數字間以空格分隔。

輸出格式:

在一行中按格式“M: n1 n2 ...”輸出,其中M是最大次數,n1、n2、……為出現次數最多的個位數字,按從小到大的順序排列。數字間以空格分隔,但末尾不得有多餘空格。

輸入樣例:

3

1234 2345 3456

輸出樣例:

3: 3 4

int main()
{
    int N, a[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, maxTime = 0;
    scanf("%d", &N);
    for (int i = 0; i < N; i++)
    {
        int t;
        scanf("%d", &t);      // 非負整數
        do
        {
            ++a[t % 10];
            t /= 10;
        } while (t != 0)      // do while處理數字為0的情況
    }
    for (int i = 0; i < 10; i++)
        if (a[i] > maxTime)
            maxTime = a[i];
    printf("%d:", maxTime);
    for (int i = 0; i < 10; i++)
        if (a[i] == maxTime)
            printf(" %d", i);
    return 0;
}

7-7 輸出陣列元素 (15 分)

本題要求編寫程式,對順序讀入的n個整數,順次計算後項減前項之差,並按每行三個元素的格式輸出結果。

輸入格式:

輸入的第一行給出正整數n(1<n≤10)。隨後一行給出n個整數,其間以空格分隔。

輸出格式:

順次計算後項減前項之差,並按每行三個元素的格式輸出結果。數字間空一格,行末不得有多餘空格。

輸入樣例:

10
5 1 7 14 6 36 4 28 50 100

輸出樣例:

-4 6 7
-8 30 -32
24 22 50
int main()
{
    int N, a[10];
    scanf("%d", &N);
    for (int i = 0; i < N; i++)  scanf("%d", &a[i]);  // n個整數
    for(int i = 0; i < N - 1; i++)
    {
        printf("%d", a[i + 1] - a[i]);
        if((i + 1) % 3 == 0 || i == N - 2)  printf("\n");
        else                                printf(" ");
    }
    return 0;
}

7-8 找出不是兩個陣列共有的元素 (20 分)

給定兩個整型陣列,本題要求找出不是兩者共有的元素。

輸入格式:

輸入分別在兩行中給出兩個整型陣列,每行先給出正整數N(≤20),隨後是N個整數,其間以空格分隔。

輸出格式:

在一行中按照數字給出的順序輸出不是兩陣列共有的元素,數字間以空格分隔,但行末不得有多餘的空格。題目保證至少存在一個這樣的數字。同一數字不重複輸出。

輸入樣例:

10 3 -5 2 8 0 3 5 -15 9 100
11 6 4 8 2 6 -5 9 0 100 8 1

輸出樣例:

3 5 -15 6 4 1

解:

    這道題網上很多答案用了三個陣列,我用了一個數組,flag陣列是用來代替陣列刪除操作的,不怎麼影響時間複雜度。

int main()
{
    int an, ancnt, bn, tmp, cnt = 0, first = 1;
    // C static陣列預設全初始化為0, flag[i]為0表示res[i]這位數不輸出
    static int res[40], flag[40];   // 用flag陣列代替刪除操作
    scanf("%d", &an);
    ancnt = an;
    for (int i = 0; i < an; i++)    // 讀第一個陣列, 跳過重複的
    {
        scanf("%d", &tmp);
        int j = 0;
        for (j = 0; j < cnt; j++)
            if (flag[j] == 1 && res[j] == tmp)
                break;
        if (j == cnt)
        {
            res[cnt] = tmp;
            flag[cnt] = 1;
            ++cnt;
        }
        else
            --ancnt;                // 記錄第一個陣列存入res多少個數!!
    }
    scanf("%d", &bn);
    for (int i = 0; i < bn; i++)    // 讀第二個陣列, res中出現過的話,對應位flag歸0,繼續下一個數
    {
        scanf("%d", &tmp);
        int j = 0;
        for (j = 0; j < cnt; j++)
            if (res[j] == tmp)    // 這裡不能判斷flag!!!!!!因為只要出現過就一定不需要了
                break;
        if (j == cnt)             // res中沒出現過
        {
            res[cnt] = tmp;
            flag[cnt] = 1;
            ++cnt;
        }
        else if (j < ancnt)       // 在第一個陣列中出現過
            flag[j] = 0;
        // 在第二個陣列中重複了就直接跳過
    }
    for (int i = 0; i < 40; i++)
        if(flag[i] == 1 && first == 1)
        {
            printf("%d", res[i]);
            first = 0;
        }
        else if(flag[i] == 1)
            printf(" %d", res[i]);
    return 0;
}

7-9 求整數序列中出現次數最多的數 (15 分)

本題要求統計一個整型序列中出現次數最多的整數及其出現次數。

輸入格式:

輸入在一行中給出序列中整數個數N(0 < N ≤ 1000),以及N個整數。數字間以空格分隔。

輸出格式:

在一行中輸出出現次數最多的整數及其出現次數,數字間以空格分隔。題目保證這樣的數字是唯一的。

輸入樣例:

10 3 2 -1 5 3 4 3 0 3 2

輸出樣例:

3 4

int main()
{
    int N = 0, num = 0, a[1000], maxTime = -1, maxIdx = -1;
    static int cnt[1000];
    scanf("%d", &N);
    for (int i = 0; i < N; i++)
    {
        int tmp, j;
        scanf("%d", &tmp);
        for (j = 0; j < num; j++)
            if (a[j] == tmp)
            {
                ++cnt[j];
                break;
            }
        if (j == num)
        {
            a[num] = tmp;
            cnt[num] = 1;
            ++num;
        }
        if (cnt[j] > maxTime)
        {
            maxTime = cnt[j];
            maxIdx = j;
        }
    }
    printf("%d %d\n", a[maxIdx], maxTime);
    return 0;
}

7-10 求最大值及其下標 (20 分)

找出給定的n個數中的最大值及其對應的最小下標(下標從0開始)。

輸入格式:

輸入在第一行中給出一個正整數n(1<n≤10)。第二行輸入n個整數,用空格分開。

輸出格式:

在一行中輸出最大值及最大值的最小下標,中間用一個空格分開。

輸入樣例:

6

2 8 10 1 9 10

輸出樣例:

10 2 

int main()
{
    int n, tmp, maxV = -2147483648, maxIdx = -1;
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%d", &tmp);
        if(tmp > maxV)
        {
            maxV = tmp;
            maxIdx = i;
        }
    }
    printf("%d %d\n", maxV, maxIdx);
    return 0;
}

7-11 特殊a串數列求和 (20 分)

給定兩個均不超過9的正整數a和n,要求編寫程式求a+aa+aaa++⋯+aa⋯a(n個a)之和。

輸入格式:

輸入在一行中給出不超過9的正整數a和n。

輸出格式:

在一行中按照“s = 對應的和”的格式輸出。

輸入樣例:

2 3

輸出樣例:

s = 246

int main()
{
    int a, n, sum = 0;
    scanf("%d%d", &a, &n);
    // 2 + 22 + 222 就是一個200,兩個20,三個2
    for(int i = 1; i <= n; i++)
        sum += a * (int)pow(10, n - i) * i;
    printf("s = %d\n", sum);
    return 0;
}

7-12 兔子繁衍問題 (15 分)

一對兔子,從出生後第3個月起每個月都生一對兔子。小兔子長到第3個月後每個月又生一對兔子。假如兔子都不死,請問第1個月出生的一對兔子,至少需要繁衍到第幾個月時兔子總數才可以達到N對?

輸入格式:

輸入在一行中給出一個不超過10000的正整數N。

輸出格式:

在一行中輸出兔子總數達到N最少需要的月數。

輸入樣例:

30

輸出樣例:

9

解:

     這道題其實手算幾個之後就找到規律了,其實就是斐波那契數列:

     第幾個月:1、2、3、4、5

     幾對兔子:1、1、2、3、5

int main()
{
    int n, f1 = 1, f2 = 1, months = 0;
    scanf("%d", &n);
    for (months = 1;; months++)
    {
        if(f1 >= n)
        {
            printf("%d\n", months);
            return 0;
        }
        f2 = f1 + f2;
        f1 = f2 - f1;
    }
    return 0;
}