MOOC哈工大2020C語言程序設計精髓練兵區編程題第八周


1 三天打漁兩天曬網(4分)

題目內容:

中國有句俗語叫“三天打魚兩天曬網”,某人從1990年1月1日起開始“三天打魚兩天曬網”,即工作三天,然后再休息兩天。問這個人在以后的某一天中是在工作還是在休息。從鍵盤任意輸入一天,編程判斷他是在工作還是在休息,如果是在工作,則輸出:He is working,如果是在休息,則輸出:He is having a rest,如果輸入的年份小於1990或者輸入的月份和日期不合法,則輸出:Invalid input。

int IsLeapYear(int year);

int CalculationDays(int year, int month, int day);

int Check(int year, int month, int day);

int main()
{
    int year, month, day, days = 0;
    scanf("%4d-%2d-%2d", &year, &month, &day);
    //檢查輸入是否有效
    if (!Check(year, month, day))
    {
        printf("Invalid input");
        return 0;
    }
    days = CalculationDays(year, month, day);
    if(days % 5 == 1 || days % 5 == 2  || days % 5 == 3)
    {
        printf("He is working");
    }
    else
    {
        printf("He is having a rest");
    }
    return 0;
}

/**
 * 計算總天數
 * @param month
 * @return
 */
int CalculationDays(int year, int month, int day)
{
    int sum = 0, days = 0;
    // 年份總天數
    for (int i = 1990; i < year; i++)
    {
        //閏年
        if(IsLeapYear(i))
        {
            days++;
        }
        days = days + 365;
    }
    //月份天數
    switch (month) {
        case 1:
            sum = 0;
            break;
        case 2:
            sum = 31;
            break;
        case 3:
            sum = 59;
            break;
        case 4:
            sum = 90;
            break;
        case 5:
            sum = 120;
            break;
        case 6:
            sum = 151;
            break;
        case 7:
            sum = 181;
            break;
        case 8:
            sum = 212;
            break;
        case 9:
            sum = 243;
            break;
        case 10:
            sum = 273;
            break;
        case 11:
            sum = 304;
            break;
        case 12:
            sum = 334;
            break;
    }
    //閏年月天數加一
    if(IsLeapYear(year))
    {
        sum++;
    }
    //年份總天數 + 月份天數 + 多少天
    days = days + sum + day;
    return days;
}

/**
 * 判斷閏年
 * @param year 輸入年份
 * @return 返回0不是閏年
 */
int IsLeapYear(int year)
{
    if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
    {
        return 1;
    }
    return 0;
}

/**
 * 檢查輸入是否有效
 * @param year
 * @param month
 * @param day
 * @return
 */
int Check(int year, int month, int day)
{
    int flag = 1;
    if(year < 1990 || month < 1 || month > 12 || day < 1 || day > 31)
    {
        flag = 0;
    }

    //二月比較特殊
    if (month == 2)
    {
        if(IsLeapYear(year)){
            if(day > 29)
            {
                flag = 0;
            }
        }
        else
        {
            if(day > 28)
            {
                flag = 0;
            }
        }
    }

    //只有30天的月份
    if(month == 4 || month == 6 || month == 9 || month == 11)
    {
        if(day > 30)
        {
            flag = 0;
        }
    }

    return flag;
}

這題用例1沒過我很懵逼,3個測試樣例輸出都沒問題

2 統計用戶輸入(4分)

題目內容:

從鍵盤讀取用戶輸入直到遇到#字符,編寫程序統計讀取的空格數目、讀取的換行符數目以及讀取的所有其他字符數目。(要求用getchar()輸入字符)

int main()
{
    int space = 0, newline = 0, others = 0;
    char c;
    printf("Please input a string end by #:\n");
    while (1)
    {
        c = getchar();
        if(c == '#')
        {
            break;
        }
        else if(c == ' ')
        {
            space++;
        }
        else if(c == '\n')
        {
            newline++;
        }
        else
        {
            others++;
        }
    }
    printf("space: %d,newline: %d,others: %d\n", space, newline, others);
    return 0;
}

3 統計正整數中指定數字的個數(4分)

題目內容:

從鍵盤輸入一個正整數number,求其中含有指定數字digit的個數。例如:從鍵盤輸入正整數number=1222,若digit=2,則1223中含有 3個2,要求用函數實現。函數原型為:int CountDigit(int number,int digit);

int CountDigit(int number,int digit);

int main()
{
    int m,n;
    printf("Input m,n:\n");
    scanf("%d,%d", &m, &n);
    printf("%d\n", CountDigit(m, n));
    return 0;
}


int CountDigit(int number,int digit)
{
    int n, count = 0;
    while (number != 0)
    {
       n = number % 10;
       if(n == digit)
       {
           count++;
       }
       number = number / 10;
    }
    return count;
}

4 玫瑰花數(4分)

題目內容:

如果一個n位正整數等於它的n個數字的n次方和,則稱該數為n位自方冪數。四位自方冪數稱為玫瑰花數。編程計算並輸出所有的玫瑰花數。

int main() 
{
    int n, a, b, c, d;
    for ( n = 1000; n < 10000; ++n) 
    {
        a = n / 1000;
        b = n / 100 % 10;
        c = n / 10 % 10;
        d = n % 10;
        if((pow(a, 4) + pow(b, 4) + pow(c, 4) + pow(d, 4)) == n)
        {
            printf("%d\n", n);
        }
    }
    return 0;
}

5 四位反序數(4分)

題目內容:

反序數就是將整數的數字倒過來形成的整數。例如,1234的反序數是4321。設N是一個四位數,它的9倍恰好是其反序數,編程計算並輸出N的值。

方法1

int main()
{
    int n, t, s = 0;
    for ( n = 1000; n < 10000; ++n)
    {
        t = n;
        while (t)
        {
            s = s * 10 + (t % 10);
            t = t / 10;
        }
        if(s == n * 9)
        {
            printf("%d\n", n);
        }
        s = 0;
    }
    return 0;
}

方法2

int main()
{
    int n, a, b, c, d;
    for ( n = 1000; n < 10000; ++n)
    {
        a = n / 1000;
        b = n / 100 % 10;
        c = n / 10 % 10;
        d = n % 10;
        if((d * 1000 + c * 100 + b * 10 + a) == n * 9)
        {
            printf("%d\n", n);
        }
    }
    return 0;
}

6 8除不盡的自然數(4分)

題目內容:

一個自然數被8除余1,所得的商被8除也余1,再將第二次的商被8除后余7,最后得到一個商為a。又知這個自然數被17除余4,所得的商被17除余15,最后得到一個商是a的2倍。求滿足以上條件的最小自然數。

int main()
{
    int n, a;
    for (n = 0; ; ++n)
    {
        a = (34 * n + 15) * 17 + 4;
        if(((n * 8 + 7) * 8 + 1) * 8 + 1 == a)
        {
            printf("%d\n", a);
            break;
        }
    }
    return 0;
}

7 矩陣轉置v1.0(4分)

題目內容:

用二維數組作為函數參數,編程計算並輸出n×n階矩陣的轉置矩陣。其中,n的值不超過10,n的值由用戶從鍵盤輸入。

#define N 10

void ReadNumber(int a[N][N], int n);

void MatrixTransposed(int arr[N][N], int n);

int main()
{
    int arr[N][N], n;
    printf("Input n:");
    scanf("%d", &n);
    printf("Input %d*%d matrix:\n", n, n);
    ReadNumber(arr,n);
    printf("The transposed matrix is:\n");
    MatrixTransposed(arr,n);
    return 0;
}

void ReadNumber(int arr[N][N],int n)
{
    int i, j;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%d",&arr[i][j]);
        }
        getchar();
    }
}

void MatrixTransposed(int arr[N][N], int n)
{
    int i,j;
    for (i = 0; i < n; ++i)
    {
        for (j = 0; j < n; ++j)
        {
            printf("%4d",arr[j][i]);
        }
        printf("\n");
    }
}

8 兔子生崽問題(4分)

題目內容:

假設一對小兔的成熟期是一個月,即一個月可長成成兔,那么如果每對成兔每個月都可以生一對小兔,一對新生的小兔從第二個月起就開始生兔子,試問從一對兔子開始繁殖,n(n<=12)月以后可有多少對兔子(即當年第n月份總計有多少對兔子,含成兔和小兔)?請編程求解該問題,n的值要求從鍵盤輸入。

參考答案:依題意,兔子的繁殖情況如圖所示。圖中實線表示成兔仍是成兔或者小兔長成成兔;虛線表示成兔生小兔。觀察分析此圖可發現如下規律:

(1)每月小兔對數 = 上個月成兔對數。

(2)每月成兔對數 = 上個月成兔對數 + 上個月小兔對數。

綜合(1)和(2)有:每月成兔對數 = 前兩個月成兔對數之和。

用fn(n=1,2,…)表示第n個月成兔對數,於是可將上述規律表示為如下遞推公式:

int f(int n);

int main() 
{
    int n;
    printf("Input n(n<=12):\n");
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) 
    {
        printf("%4d", f(i));
    }
    printf("\nTotal=%d\n", f(n));
    return 0;
}

int f(int n)
{
    if(n == 1)
    {
        return 1;
    }
    else if(n == 2)
    {
        return 2;
    }
    return f(n -1) + f(n - 2);
}

9 抓交通肇事犯(4分)

題目內容:

一輛卡車違犯交通規則,撞人后逃跑。現場有三人目擊事件,但都沒記住車號,只記下車號的一些特征。甲說:牌照的前兩位數字是相同的;乙說:牌照的后兩位數字是相同的,但與前兩位不同;丙是位數學家,他說:四位的車號剛好是一個整數的平方。現在請根據以上線索幫助警方找出車號以便盡快破案。

[提示]:假設這個4位數的前兩位數字都是i,后兩位數字都是j,則這個可能的4位數

k = 1000*i + 100*i + 10*j + j

式中,i和j都在0~9變化。此外,還應使k=m*m,m是整數。由於k是一個4位數,所以m值不可能小於31。

int main()
{
    int k, m;
    for (m = 31; m <= 99; ++m)
    {
        k = m * m;
        if(k / 1000 == k % 1000 / 100 && k % 100 / 10 == k % 10 && k % 100 != (k / 1000) * 10 + k % 1000 / 100)
        {
            printf("k=%d,m=%d\n", k, m);
        }
    }
    return 0;
}

10 檢驗並打印幻方矩陣(4分)

題目內容:

幻方矩陣是指該矩陣中每一行、每一列、每一對角線上的元素之和都是相等的。從鍵盤輸入一個5×5的矩陣並將其存入一個二維整型數組中,檢驗其是否為幻方矩陣,並將其按指定格式顯示到屏幕上。

#define N 5

int Check(int arr[N][N], int n);

int main() 
{
    int arr[N][N];
    //獲取輸入
    for (int i = 0; i < N; ++i)
    {
        for (int j = 0; j < N; ++j)
        {
            scanf("%d", &arr[i][j]);
        }
        getchar();
    }
    if(Check(arr,N))
    {
        printf("It is a magic square!\n");
        for (int i = 0; i < N; ++i)
        {
            for (int j = 0; j < N; ++j)
            {
                printf("%4d", arr[i][j]);
            }
            printf("\n");
        }
    }
    else
    {
        printf("It is not a magic square!\n");
    }

    return 0;
}

int Check(int arr[N][N], int n)
{
    int i, j, sum, s1, s2, s3, s4, flag = 1;
    for (i = 0; i < n; ++i)
    {
        s1 = s2 = s3 = s4 = 0;
        for (j = 0; j < n; ++j)
        {
            //行合
            s1 += arr[i][j];
            //列合
            s2 += arr[j][i];

            //對角    00,11,22,33,44
            s3 += arr[j][j];
            //       04,13,22,31,40
            s4 += arr[j][N - j - 1];

        }
        //將第一行的合保存
        if(i == 0)
        {
            sum = s1;
        }
        //有一個不相等就退出
        if(s1 != sum || s2 != sum || s3 != sum || s4 != sum)
        {
           flag = 0;
           break;
        }
    }
    return flag;
}

 


免責聲明!

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



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