蓝桥杯练习试题代码及讲解

蓝桥杯练习试题及思路讲解

入门训练

0001 A+B 问题

问题描述

  输入 A、B,输出 A+B。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  输入的第一行包括两个整数,由空格分隔,分别表示 A、B。

输出格式

  输出一行,包括一个整数,表示 A+B 的值。

样例输入

  12 45

样例输出

  57

数据规模与约定

  10000 <= A, B <= 10000。

本题的C源代码如下:

#include <stdio.h>

int main()
{
    int a, b;
    scanf("%d%d", &a, &b);
    printf("%d", a + b);
    return 0;
}

0002 序列求和

问题描述

  求1+2+3+...+n的值。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  输入包括一个整数n。

输出格式

  输出一行,包括一个整数,表示1+2+3+...+n的值。

样例输入

  4

样例输出

  10

样例输入

  100

数据规模与约定

  1 <= n <= 1,000,000,000

提示

  • 循环累加的方法是最直接的,然而,当数据规模很大时,这种“暴力”的方法往往会导致超时。如果使用 1000000000 作为你的程序的输入,你的程序是不是能在规定的上面规定的时限内运行出来。此时你可以使用求和公式,n = (1 + n) * n / 2。

  • 本题另一个要值得注意的地方是答案的大小不在你的语言默认的整型 (int) 范围内,如果使用整型来保存结果,会导致结果错误。如果你使用 C++ 或 C 语言而且准备使用 printf 输出结果,则你的格式字符串应该写成 %I64d 以输出 long long 类型的整数。

本题的C源代码如下:

#include <stdio.h>

int main()
{
    long long int n = 0;
    scanf("%d", &n);
    n = (1 + n) * n / 2;
    printf("%I64d\n", n);
    return 0;
}

0003 圆的面积

问题描述

  给定圆的半径r,求圆的面积。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  输入包含一个整数r,表示圆的半径。

输出格式

  输出一行,包含一个实数,四舍五入保留小数点后7位,表示圆的面积。

样例输入

  4

样例输出

  50.2654825

数据规模与约定

  1 <= r <= 10000

提示

  • 本题对精度要求较高,请注意π的值应该取较精确的值。你可以使用常量来表示 π,比如PI=3.14159265358979323,也可以使用数学公式来求 π,比如 PI=atan(1.0)*4 。

本题的C源代码如下:

#include <stdio.h>
#define PI 3.1415926535897932384626
int main()
{
    int r = 0;
    scanf("%d", &r);
    double area = 0;
    area = r * r * PI;
    printf("%.7lf\n", area);
    return 0;
}

0004 Fibonacci 数列

问题描述

  Fibonacci 数列的递推公式为:Fn=Fn-1+Fn-2,其中 F1=F2=1。

  当 n 比较大时,Fn 也非常大,现在我们想知道,Fn 除以 10007 的余数是多少。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  输入包含一个整数n。

输出格式

  输出一行,包含一个整数,表示Fn除以10007的余数。

样例输入

  10

样例输出

  55

样例输入

  22

样例输出

  7704

数据规模与约定

  1 <= n <= 1,000,000。

提示

  • 在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单。

本题的C源代码如下:

思路:使用三个变量,每次循环根据前两个变量得到第三个的值,然后将第二、三个变量的值分别赋值给第一个和第二个,然后再根据前两个变量得到第三个的值,如此往复。

#include <stdio.h>

int main()
{
    int m = 1, n = 1, x = 0, input = 0; // m , n 代表前俩数,x 代表当前数
    scanf("%d", &input);
    if (input == 1 || input == 2)
    {
        x = 1;
        printf("%d\n", x);
    }
    else
    {
        for (input; input > 2; input--)
        {
            x = (m + n) % 10007;
            m = n;
            n = x;
        }
        printf("%d\n", x);
    }
    return 0;
}

递归法输出斐波那契数列任意一位:

#include <stdio.h>

int getFib(int i)
{
    if (i == 1 || i == 2)
        return 1;
    else
        return getFib(i - 1) + getFib(i - 2);
}
int main()
{
    int i;
    scanf("%d", &i);
    printf("%d", getFib(i));
    return 0;
}

输出斐波那契数列前 20 个数,每 5 个数换一行:

#include <stdio.h>

int main()
{
    int m = 1, n = 1, x = 0;
    int counter;
    printf("%d %d ", m, n);
    for (counter = 3; counter <= 50; counter++)
    {
        x = m + n;
        if (counter % 5 == 0)
            printf("%d\n", x);
        else
            printf("%d ", x);
        m = n;
        n = x;
    }
    return 0;
}

基础练习

0005 闰年判断  

问题描述

  给定一个年份,判断这一年是不是闰年。

  当以下情况之一满足时,这一年是闰年:

  1. 年份是4的倍数而不是100的倍数;

  2. 年份是400的倍数。

  其他的年份都不是闰年。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  输入包含一个整数y,表示当前的年份。

输出格式

  输出一行,如果给定的年份是闰年,则输出 yes,否则输出 no。

样例输入

  2013

样例输出

  no

样例输入

  2016

样例输出

  yes

数据规模与约定

  1990 <= y <= 2050。

本题的C源代码如下:

#include <stdio.h>

int main()
{
    int y = 0;
    scanf("%d", &y);
    if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
        printf("yes");
    else
        printf("no");
    return 0;
}

0006 01字串

问题描述

  对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:

  00000

  00001

  00010

  00011

  00100

  请按从小到大的顺序输出这32种01串。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  本试题没有输入。

输出格式

  输出32行,按从小到大的顺序每行一个长度为5的01串。

样例输出

  00000
  00001
  00010
  00011
  <以下部分省略>

提示

  • 评测系统不支持在 for 循环的循环条件中声明变量。

本题的C源代码如下:

#include <stdio.h>

int main()
{
    int a[5] = {0}, i = 0, k = 4;
    for (i = 0; i < 32; i++)
    {
        int n = i, j = 0;
        while (n != 0)
        {
            a[j++] = n % 2;
            n /= 2;
        }
        for (k = 4; k >= 0; k--)
        {
            printf("%d", a[k]);
        }
        printf("\n");
    }
    return 0;
}

0007 字母图形

问题描述

  利用字母可以组成一些美丽的图形,下面给出了一个例子:

  ABCDEFG

  BABCDEF

  CBABCDE

  DCBABCD

  EDCBABC

  这是一个5行7列的图形,请找出这个图形的规律,并输出一个n行m列的图形。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  输入一行,包含两个整数n和m,分别表示你要输出的图形的行数的列数。
输出格式

  输出n行,每个m个字符,为你的图形。
样例输入
  5 7

样例输出

  ABCDEFG

  BABCDEF

  CBABCDE

  DCBABCD

  EDCBABC

数据规模与约定

  1 <= n, m <= 26

提示

  • 字母默认为 'A' ,字母所在位置的横坐标与纵坐标之差的绝对值与 'A' 相加,得到该位置的字符。C 语言使用函数 abs() 计算绝对值,在使用该函数时需要引入头文件:include <stdlib.h>

本题的C源代码如下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int x = 0, y = 0, i = 0, j = 0;
    scanf("%d %d", &x, &y);
    char arr[x][y], str = 'A';
    for (i = 0; i < x; i++)
    {
        for (j = 0; j < y; j++)
        {
            arr[i][j] = str + abs(i - j);
        }
    }
    for (i = 0; i < x; i++)
    {
        for (j = 0; j < y; j++)
        {
            printf("%c", arr[i][j]);
        }
        printf("\n");
    }
    return 0;
}

0008 数列特征

问题描述

  给出n个数,找出这n个数的最大值,最小值,和。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  第一行为整数n,表示数的个数。

  第二行有n个数,为给定的n个数,每个数的绝对值都小于10000。

输出格式

  输出三行,每行一个整数。第一行表示这些数中的最大值,第二行表示这些数中的最小值,第三行表示这些数的和。

样例输入

  5

  1 3 -2 4 5

样例输出

  5

  -2

  11

数据规模与约定

  1 <= n <= 10000。

本题的C源代码如下:

#include <stdio.h>

int main()
{
    int i, j, max, min, sum = 0;
    scanf("%d", &j);
    int num[j];
    for (i = 0; i < j; i++)
    {
        scanf("%d", &num[i]);
        sum += num[i];
    }
    max = min = num[0];
    for (i = 0; i < j; i++)
    {
        if (num[i] > max)
            max = num[i];
        if (num[i] < min)
            min = num[i];
    }
    printf("%d\n%d\n%d\n", max, min, sum);
    return 0;
}

0009 查找整数

问题描述

  给出一个包含n个整数的数列,问整数a在数列中的第一次出现是第几个。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  第一行包含一个整数n。

  第二行包含n个非负整数,为给定的数列,数列中的每个数都不大于10000。

  第三行包含一个整数a,为待查找的数。

输出格式

  如果a在数列中出现了,输出它第一次出现的位置(位置从1开始编号),否则输出-1。

样例输入

  6
  1 9 4 8 3 9
  9

样例输出

  2

数据规模与约定

  1 <= n <= 1000。

本题的C源代码如下:

#include <stdio.h>

int main()
{
    int m, n, i, j = -1;
    scanf("%d", &m);
    int num[m];
    for (i = 0; i < m; i++)
    {
        scanf("%d", &num[i]);
    }
    scanf("%d", &n);
    for (i = 0; i < m; i++)
    {
        if (num[i] == n)
        {
            j = i + 1;
            break;
        }
    }
    printf("%d", j);
    return 0;
}

0010 杨辉三角形

问题描述

  杨辉三角形又称 Pascal 三角形,它的第 i+1 行是 $ (a+b)^i$ 的展开式的系数。

  它的一个重要性质是:三角形中的每个数字等于它两肩上的数字相加。

  下面给出了杨辉三角形的前 17 行:

                                            1
                                          1  1
                                         1  2  1
                                       1  3  3  1
                                     1  4  6  4  1
                                   1  5  10  10  5  1
                                 1  6  15  20  15  6  1
                               1  7  21  35  35  21  7  1
                             1  8  28  56  70  56  28  8  1
                          1  9  36  84  126  126  84  36  9  1
                      1  10  45  120  210  252  210  120  45  10  1
                    1  11  55  165  330  462  462  330  165  55  11  1
                 1  12  66  220  495  792  924  792  495  220  66  12  1
              1  13  78  286  715  1287  1716  1716  1287  715  286  78  13  1
        1  14  91  364  1001  2002  3003  3432  3003  2002  1001  364  91  14  1
    1  15  105  455  1365  3003  5005  6435  6435  5005  3003  1365  455  105  15  1
1  16  120  560  1820  4368  8008  11440  12870  11440  8008  4368  1820  560  120  16  1
......

  给出n,输出它的前n行。

  时间限制:1.0s   内存限制:256.0MB

输入格式

  输入包含一个数n。

输出格式

  输出杨辉三角形的前n行。每一行从这一行的第一个数开始依次输出,中间使用一个空格分隔。请不要在前面输出多余的空格。

样例输入

  4

样例输出

  1
  1 1
  1 2 1
  1 3 3 1

数据规模与约定

  1 <= n <= 34

提示

  • 每个杨辉三角数用 $num[x,y]$ 的形式表示,num 表示数值,x,y 是这个数在二维数组中的横纵坐标。如下表:

1[0,0]
1[1,0]1[1,1]
1[2,0]2[2,1]1[2,2]
1[3,0]3[3,1]3[3,2]1[3,3]
1[4,0]4[4,1]6[4,2]4[4,3]1[4,4]
1[5,0]5[5,1]10[5,2]10[5,3]5[5,4]1[5,5]
1[6,0]5[6,1]10[6,2]10[6,3]5[6,4]1[6,5]
  • 当 y==0 或者 x==y 时,num = 1。当 x==y 时换行。

  • 其他情况,num = num[x-1, y-1] + num[x-1, y] 。

本题的C源代码如下:

数组法:

#include <stdio.h>

int main()
{
    int n = 0;                   // n 表示输出的层数
    scanf("%d", &n);             // 用户输入要输出的层数,将值传递给 n
    int x = 0, y = 0, num[n][n]; // x, y 用于循环计数,二维数组 num 用于存储杨辉三角数。
    for (x = 0; x < n; x++)      // 控制 x y 坐标变化,计算杨辉三角数并存储进数组里
    {
        num[x][0] = 1;
        for (y = 1; y < x; y++)
            num[x][y] = num[x - 1][y - 1] + num[x - 1][y];
        num[x][x] = 1;
    }
    for (x = 0; x < n; x++)
    {
        for (y = 0; y <= x; y++)
            printf("%d ", num[x][y]);
        printf("\n");
    }
    return 0;
}

以等腰三角形样式输出:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int s = 1, h;                   // 数值和三角形层数
    int i, j;                       // 循环计数
    scanf("%d", &h);                // 输入层数
    printf("1\n");                  // 输出第一个 1
    for (i = 2; i <= h; s = 1, i++) // 行数 i 从 2 到层高
    {
        printf("1 ");                // 第一个 1
        for (j = 1; j <= i - 2; j++) // 列位置 j 绕过第一个直接开始循环
            //printf("%d ", (s = (i - j) / j * s));
            printf("%d ", (s = (i - j) * s / j));
        printf("1\n"); // 最后一个 1,换行
    }
    getchar(); // 暂停等待

    scanf("%d", &s);
    return 0;
}

时间和空间最优算法:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main()
{
    int s = 1, h;                   // 数值和高度
    int i, j;                       // 循环计数
    scanf("%d", &h);                // 输入层数
    printf("1\n");                  // 输出第一个 1
    for (i = 2; i <= h; s = 1, i++) // 行数 i 从 2 到层高
    {
        printf("1 ");                // 第一个 1
        for (j = 1; j <= i - 2; j++) // 列位置 j 绕过第一个直接开始循环
            printf("%d ", (s = (i - j) * s / j));
        printf("1\n"); // 最后一个 1,换行
    }
    getchar(); // 暂停等待
    system("pause");
    return 0;
}

0011 特殊的数字/水仙花数

问题描述

  153 是一个非常特殊的数,它等于它的每位数字的立方和,即 153=1×1×1+5×5×5+3×3×3 。编程求所有满足这种条件的三位十进制数。

​ 时间限制:1.0s   内存限制:256.0MB

输出格式

  按从小到大的顺序输出满足条件的三位十进制数,每个数占一行。

提示

  枚举+循环判断

本题的C源代码如下:

#include <stdio.h>

int main()
{
    int i, j, k;
    for (i = 1; i <= 9; i++)
    {
        for (j = 0; j <= 9; j++)
        {
            for (k = 0; k <= 9; k++)
            {
                if (i * i * i + j * j * j + k * k * k == i * 100 + j * 10 + k)
                    printf("%d\n", i * 100 + j * 10 + k);
            }
        }
    }
    return 0;
}

解法②:

#include <stdio.h>
int main()
{
    int num, hd, td, sd;
    for (num = 100; num < 1000; num++)
    {
        hd = num % 10;
        td = (num - num / 100 * 100) / 10;
        sd = num / 100;
        if (hd * hd * hd + td * td * td + sd * sd * sd == num)
        {
            printf("%d\n", num);
        }
    }
    return 0;
}

0012 回文数

问题描述

  1221是一个非常特殊的数,它从左边读和从右边读是一样的,编程求所有这样的四位十进制数。

​ 时间限制:1.0s   内存限制:512.0MB

输出格式

  按从小到大的顺序输出满足条件的四位十进制数。

提示

  • 枚举加判断。

本题的C源代码如下:

#include <stdio.h>

int main()
{
    int g, s, b, q, num; // g s b q 取自 "个十百千" 拼音首字母
    for (num = 1000; num < 10000; num++)
    {
        g = num % 10;
        s = (num - num / 100 * 100) / 10;
        b = num / 100 % 10;
        q = num / 1000;
        if (g == q && s == b)
        {
            printf("%d\n", num);
        }
    }
    return 0;
}

0013 特殊回文数

问题描述

  123321是一个非常特殊的数,它从左边读和从右边读是一样的。

  输入一个正整数n, 编程求所有这样的五位和六位十进制数,满足各位数字之和等于n 。

​ 时间限制:1.0s   内存限制:512.0MB

输入格式

  输入一行,包含一个正整数n。

输出格式

  按从小到大的顺序输出满足条件的整数,每个整数占一行。

样例输入

  52

样例输出

  899998
  989989
  998899

数据规模和约定

  1<=n<=54。

提示

  • 枚举加判断。

本题的C源代码如下:

#include <stdio.h>

int main()
{
    int g, s, b, q, w, sw, num, n; // g s b q 取自 "个、十、百、千、万、十万" 拼音首字母
    scanf("%d", &n);
    for (num = 10000; num < 999999; num++)
    {
        g = num % 10;
        s = num / 10 % 10;
        b = num / 100 % 10;
        q = num / 1000 % 10;
        w = num / 10000 % 10;
        sw = num / 100000 % 10;
        if (sw == 0 && g == w && s == q && g + s + b + q + w == n)
            printf("%d\n", num);
        else if (sw != 0 && sw == g && s == w && b == q && g + s + b + q + w + sw == n)
            printf("%d\n", num);
    }
    return 0;
}

0014 十进制转十六进制  

问题描述

  十六进制数是在程序设计时经常要使用到的一种整数的表示方式。它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16个符号,分别表示十进制数的0至15。十六进制的计数方法是满16进1,所以十进制数16在十六进制中是10,而十进制的17在十六进制中是11,以此类推,十进制的30在十六进制中是1E。

  给出一个非负整数,将它表示成十六进制的形式。

  时间限制:1.0s   内存限制:512.0MB

输入格式

  输入包含一个非负整数a,表示要转换的数。0<=a<=2147483647

输出格式

  输出这个整数的16进制表示

样例输入

30

样例输出

1E

提示

  • 按除 16 倒取余数(也可使用格式输出)。

  • 十六进制格式化输出使用 %x

本题的C源代码如下:

倒取余数,这里建议使用 do while 循环,因为当 num = 0 时程序也必须执行一次以输出 0。

#include <stdio.h>

int main()
{
    int num = 0, hex = 16, i = 0, arr[20];
    scanf("%d", &num);
    do
    {
        arr[i] = num % hex;
        i++;
        num /= hex;
    } while (num);
    for (i = i - 1; i >= 0; i--)
    {
        if (arr[i] < 10)
            printf("%d", arr[i]);
        else
            printf("%c", arr[i] + 'A' - 10);
    }
    printf("\n");
    return 0;
}

格式化输出:

#include <stdio.h>

int main()
{
    int num = 0, hex = 16, i = 0, arr[20];
    scanf("%d", &num);
    printf("%x\n",&num);
    return 0;
}

0015 十六进制转十进制

问题描述

  从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出。

  注:十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。

  时间限制:1.0s   内存限制:512.0MB

样例输入

  FFFF

样例输出

  65535

提示

  • 按16进制展开。

  • 按数位依次操作,每次将前面的乘16,再加上当前数位的值。

本题的C源代码如下:

#include <stdio.h>
int power(int p, int num);
int main()
{
    char num[8] = "xxxxxxxx"; // 存储输入的数组
    gets(num);
    int i = 0, n = 0, p = 0; // i 循环计数,n 累计每一位的数值,p 每一位的次方
    for (i = 8; i >= 0; i--)
    {
        if (num[i] != 120 && num[i] != 0)
        {
            n += power(p, num[i]);
            p++;
        }
    }
    printf("%d\n", n);
    return 0;
}
int power(int p, int num)
{
    int i = 0;
    if (num >= '0' && num <= '9') // 如果是 1-9 ,就使值等于 1-9
    {
        num -= '0';
    }
    else if (num >= 'A' && num <= 'F') // 如果是 A-F ,就使值等于 10-15
    {
        num = num - 'A' + 10;
    }
    for (i = 0; i < p; i++) // 幂运算
    {
        num = num * 16;
    }
    return num;
}

0016 十六进制转八进制  

问题描述

  给定n个十六进制正整数,输出它们对应的八进制数。

  时间限制:1.0s   内存限制:512.0MB

输入格式
  输入的第一行为一个正整数 n (1<=n<=10)。

  接下来n行,每行一个由0~9、大写字母A~F组成的字符串,表示要转换的十六进制正整数,每个十六进制数长度不超过100000。

输出格式

  输出n行,每行为输入对应的八进制正整数。

  【注意】

  输入的十六进制数不会有前导0,比如012A。

  输出的八进制数也不能有前导0。

样例输入
  2
  39
  123ABC

样例输出
  71
  4435274

提示

  • 先将十六进制数转换成二进制数,再由二进制数转换成八进制。

本题的C源代码如下:

0017 数列排序

问题描述

  给定一个长度为n的数列,将这个数列按从小到大的顺序排列。1<=n<=200

  时间限制:1.0s   内存限制:512.0MB

输入格式

  第一行为一个整数n。
  第二行包含n个整数,为待排序的数,每个整数的绝对值小于10000。

输出格式

  输出一行,按从小到大的顺序输出排序后的数列。

样例输入

  5
  8 3 6 4 9

样例输出

  3 4 6 8 9

本题的C源代码如下:

#include <stdio.h>

int main()
{
    int n = 0, i, j, temp;
    scanf("%d", &n);
    int a[n];
    for (i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
    }
    j = n;
    for (j; j > 0; j--)
    {
        for (i = 0; i < j; i++)
        {
            if (a[i] > a[i + 1])
            {
                temp = a[i];
                a[i] = a[i + 1];
                a[i + 1] = temp;
            }
        }
    }
    for (i = 0; i < n; i++)
    {
        printf("%d ", a[i]);
    }
    return 0;
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值