2023年第15届蓝桥杯模拟赛第二期(c语言)

简介: 2023年第15届蓝桥杯模拟赛第二期(c语言)

作为一个只学了一个多月的大一新生,只会c语言,怎么写完蓝桥杯模拟赛?学完函数和数组部分就够了!当然,学校教的肯定是不够的,去b站看鹏哥的课,看完函数和数组你就能写!


不需要懂算法,需要的只是思路,算不算法不重要(当然,我也没学算法),讲解我放在注释里面了。


另外两个答案是c++和python的,大一只学了c看不懂啊,所以我就萌生了自己写一篇c语言解法的想法,作为一个大一新生的视角解题,用词可能不是很准确,请见谅


第一题

问题描述

 小蓝要在屏幕上放置一行文字,每个字的宽度相同。

 小蓝发现,如果每个字的宽为 36 像素,一行正好放下 30 个字,字符之间和前后都没有任何空隙。

 请问,如果每个字宽为 10 像素,字符之间不包含空隙,一行可以放下多少个字?

答案提交

 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


答案

(36*10)/10=108


第二题

问题描述

 求 2**2023%1000,即 2的2023次方除以1000的余数。

答案提交

 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


答案

608


思路为找规律


基础版本:(我的写法)


后三位存在循环,只是计算量比较大


进阶答案(快速幂算法):(某个佬的写法)


计算 2的13次方,首先,我们将指数13转换为二进制形式,得到1101。


然后,我们从右到左遍历每一位:


第一位是1,所以我们将结果乘以 2的20次方=2的1次方=2;

第二位是0,所以我们不需要乘以任何东西;

第三位是1,所以我们将结果乘以 2的2^2次方=2的4次方=16;

第四位是1,所以我们将结果乘以 2的2^3次方=2的8次方=256。

所以,2^13=2×16×256=8192。

#include<stdio.h>
 
int power(int n, int p, int m) 
{
    int three = 1;
    while (p > 0) 
    {
        if (p & 1) 
        {
            three = (three * n) % m;
        }
        n = (n * n) % m;
        p >>= 1;
    }
    return three;
}
 
int main()
{
  printf("%d",power(2,2023,1000));
  return 0;
}


第三题

问题描述

 如果一个正整数转化成二进制与转换成八进制后所有数位的数字之和相等,则称为数位和相等的数。

 前几个数位和相等的正整数为 1, 8, 9, 64, ……

 请问第 23 个数位和相等的正整数是多少?

答案提交

 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


答案

4169

#include <stdio.h>  
int main()
{
    int sum_two = 0, sum_eight = 0;
    int two[32] = { 0 };
    int eight[32] = { 0 };
    int count = 0;
    int i = 0, j = 0;
    int n = 0, m = 0;
    for (i = 1;count < 23;i++)
    {
        sum_two = 0, sum_eight = 0;
        for (j = 0, n = i; j < 32; j++)
        {
            two[j] = n & 1;
            sum_two += two[j];
            n >>= 1;
        }
 
        for (j = 0, m = i; j < 32; j++)
        {
            eight[j] = m & 7;
            sum_eight += eight[j];
            m >>= 3;
        }
 
        if (sum_two == sum_eight)
        {
            count++;
            printf("第%d位:%d\n", count, i);
        }
    }
    return 0;
}


第四题

问题描述

 对于以下这些数(6行,每行6个,共36个),请问约数个数最多的是哪个?(如果有多个,请回答出现最早的那个)

 393353 901440 123481 850930 423154 240461

 373746 232926 396677 486579 744860 468782

 941389 777714 992588 343292 385198 876426

 483857 241899 544851 647930 772403 109929

 882745 372491 877710 340000 659788 658675

 296521 491295 609764 718967 842000 670302

答案提交

 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。

答案

901440

#include<stdio.h>
 
int count(int arr)
{
  int i = arr;
  int count = 0;
  while (i > 0)
  {
    if (arr % i == 0)
    {
      count++;
    }
    i--;
  }
  return count;
}
 
int main()
{
  int arr[6][6]={ 393353,901440,123481,850930,423154,240461,
          373746,232926,396677,486579,744860,468782,
          941389,777714,992588,343292,385198,876426,
          483857,241899,544851,647930,772403,109929,
          882745,372491,877710,340000,659788,658675,
          296521,491295,609764,718967,842000,670302};
  int  i=0,j=0;
  for (i = 0;i < 6;i++)
  {
    for (j = 0;j < 6;j++)
    {
      printf("%d:%d个\n",arr[i][j],count(arr[i][j]));
    }
  }
  return 0;
}

第五题

问题描述

 小蓝有一个01矩阵。他打算将第一行第一列的 0 变为 2 。变化过程有传染性,每次 2 的上下左右四个相邻的位置中的 0 都会变成 2 。直到最后每个 2 的周围都是 1 或 2 结束。

 请问,最终矩阵中有多少个 2 ?

 以下是小蓝的矩阵,共 30 行 40 列。

 0000100010000001101010101001001100000011

 0101111001111101110111100000101010011111

 1000010000011101010110000000001011010100

 0110101010110000000101100100000101001001

 0000011010100000111111001101100010101001

 0110000110000000110100000000010010100011

 0100110010000110000000100010000101110000

 0010011010100110001111001101100110100010

 1111000111101000001110010001001011101101

 0011110100011000000001101001101110100001

 0000000101011000010011111001010011011100

 0000100000011001000100101000111011101100

 0010110000001000001010100011000010100011

 0110110000100011011010011010001101011011

 0000100100000001010000101100000000000010

 0011001000001000000010011001100101000110

 1110101000011000000100011001001100111010

 0000100100111000001101001000001010010001

 0100010010000110100001100000110111110101

 1000001001100010011001111101011001110001

 0000000010100101000000111100110010101101

 0010110101001100000100000010000010110011

 0000011101001001000111011000100111010100

 0010001100100000011000101011000000010101

 1001111010010110011010101110000000101110

 0110011101000010100001000101001001100010

 1101000000010010011001000100110010000101

 1001100010100010000100000101111111111100

 1001011010101100001000000011000110110000

 0011000100011000010111101000101110110001

答案提交

 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。


答案

541

#include<stdio.h>
 
void change(char ch[30][41], int i, int j)
{
  if (ch[i][j + 1] == '0' && j != '39')
  {
    ch[i][j + 1] = '2';
    change(ch, i, j + 1);
  }
  if (ch[i + 1][j] == '0' && i != '29')
  {
    ch[i + 1][j] = '2';
    change(ch, i + 1, j);
  }
  if (ch[i - 1][j] == '0' && i != '0')
  {
    ch[i - 1][j] = '2';
    change(ch, i - 1, j);
  }
  if (ch[i][j - 1] == '0' && j != '0')
  {
    ch[i][j - 1] = '2';
    change(ch, i, j - 1);
  }
}
 
int main()
{
  char ch[30][41]={"0000100010000001101010101001001100000011",
           "0101111001111101110111100000101010011111",
           "1000010000011101010110000000001011010100",
           "0110101010110000000101100100000101001001",
           "0000011010100000111111001101100010101001",
           "0110000110000000110100000000010010100011",
           "0100110010000110000000100010000101110000",
           "0010011010100110001111001101100110100010",
           "1111000111101000001110010001001011101101",
           "0011110100011000000001101001101110100001",
           "0000000101011000010011111001010011011100",
           "0000100000011001000100101000111011101100",
           "0010110000001000001010100011000010100011",
           "0110110000100011011010011010001101011011",
           "0000100100000001010000101100000000000010",
           "0011001000001000000010011001100101000110",
           "1110101000011000000100011001001100111010",
           "0000100100111000001101001000001010010001",
           "0100010010000110100001100000110111110101",
           "1000001001100010011001111101011001110001",
           "0000000010100101000000111100110010101101",
           "0010110101001100000100000010000010110011",
           "0000011101001001000111011000100111010100",
           "0010001100100000011000101011000000010101",
           "1001111010010110011010101110000000101110",
           "0110011101000010100001000101001001100010",
           "1101000000010010011001000100110010000101",
           "1001100010100010000100000101111111111100",        
           "1001011010101100001000000011000110110000",
           "0011000100011000010111101000101110110001" };
  int i=0,j=0;
  int count=0;
  ch[0][0]='2';
  change(ch,i,j);
  for (i = 0;i < 30;i++)
  {
    for (j = 0;j < 40;j++)
    {
      if (ch[i][j] == '2')
      {
        count++;
      }
    }
  }
  printf("%d",count);
  return 0;
}


第六题

问题描述

 给定一个正好六位的正整数 x,请将 x 循环左移一位后输出。

 所谓循环左移一位,是指将原来的十万位变为个位,原来的万位到个位向左移动依次变为十万位到十位。

 例如:194910 左移一位变为 949101 。

 又如:987123 左移一位变为 871239 。

输入格式

 输入一行包含一个整数 x 。保证输入的 x 正好包含 6 个十进制数位,而且十万位和万位上的数字均不为 0 。

输出格式

 输出一行包含一个整数,表示答案。

样例输入

194910

样例输出

949101


答案

#include<stdio.h>
int main()
{
  int x=0;
  int a=0,b=0;
  scanf("%d",&x);
  a=x%100000;
  b=x/100000;
  printf("%d",10*a+b);
  return 0;
}

第七题

问题描述

 给定一个整数,对这个整数的一次转换是指将这个整数变为这个整数的所有数位上的非零数字的乘积。

 例如,对 123456789 进行一次转换变为 1*2*3*4*5*6*7*8*9=362880,再进行一次转换变为 3*6*2*8*8=2304,再进行一次转换变为 2*3*4=24,再进行一次转换变为 8。

 给定一个整数,请依次将转换过程中经历的每个整数输出,直到小于 10 。

输入格式

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

输出格式

 输出多行,每行包含一个整数。

样例输入

123456789

样例输出

362880

2304

24

8

评测用例规模与约定

 对于 50% 的评测用例,1 <= n <= 10**9 (10的9次方)。

 对于所有评测用例,1 <= n <= 10**18 (10的18次方)。

答案

void print(int n)
{
  int multiply = 1;
  while (n > 10)
  {
    multiply *= (n % 10 == 0) ? 1 : n % 10;
    n /= 10;
  }
  printf("%d\n", multiply);
  if (multiply > 10)
  {
    print(multiply);
  }
}
 
int main()
{
  int n=0;
  scanf("%d",&n);
  print(n);
  return 0;
}

第八题

问题描述

 输入一个仅包含小写英文字母的字符串,请问这个字符串中的最后一元音是什么。

 在英文中,a, e, i, o, u 共 5 个字母是元音字母,其它字母不是元音字母。

输入格式

 输入一行包含一个字符串,仅由小写英文字符组成,字符串中至少包含一个元音字母。

输出格式

 输出一行包含一个字符,表示答案。

样例输入

lanqiao

样例输出

o

样例输入

cup

样例输出

u

评测用例规模与约定

 对于所有评测用例,1 <= 字符数量 <= 10000 。


答案

#include<stdio.h>//不用指针
int main()
{
  char ch[10000];
  char ch1;
  scanf("%s",ch);
  int i=0;
  for (;ch[i] != '\0';i++)
  {
    if (ch[i] == 'a' || ch[i] == 'e' || ch[i] == 'i' || ch[i] == 'o' || ch[i] == 'u')
    {
      ch1 = ch[i];
    }
  }
  printf("%c",ch1);
  return 0;
}


#include<stdio.h>//指针写法
int main()
{
  char ch[10000];
  char ch1;
  scanf("%s",ch);
  char* p=ch;
  while (*p != '\0')
  {
    if (*p == 'a' || *p == 'e' || *p == 'i' || *p == 'o' || *p == 'u')
    {
      ch1=*p;
    }
    p++;
  }
  printf("%c",ch1);
  return 0;
}


第九题

问题描述

 小蓝站在一个 n 行 m 列的方格图中间,方格图的每一个方格上都标有一个正整数。

 如果两个相邻方格(上下左右四个方向相邻)内的数的最大公约数大于 1 ,则可以从其中一个方格移动到另一个方格,当然也可以从另一个方格移回第一个方格。

 假设小蓝开始时站在第 r 行第 c 列,请问小蓝可以移动到方格图内的多少个方格?

输入格式

 输入的第一行包含两个整数 n, m ,用一个空格分隔,表示方格图的行数和列数。

 接下来 n 行,每行包含 m 个正整数,相邻整数间用一个空格分隔,依次表示方格图中从第 1 行到第 n 行,每行从第 1 列到第 m 列中的数。

 接下来一行包含两个整数 r, c,用一个空格分隔,表示小蓝所在的行号和列号。

输出格式

 输出一行包含一个整数,表示答案。

样例输入

3 4

3 6 5 5

2 4 3 5

7 8 3 8

3 2

样例输出

5

评测用例规模与约定

 对于50%的评测用例,1 <= n, m <= 100,方格图中的每个数不超过 10**5 (10的5次方)。

 对于所有评测用例,1 <= n, m <= 1000,方格图中的每个数不超过 10**9 (10的9次方)。


答案

#include<stdio.h>
 
//函数的声明,以防顺序问题造成找不到函数(从上到下)
int gongyueshu(int a, int b);
void change(int arr1[1000][1000], int arr2[1000][1000], int r, int c, int n, int m);
 
int gongyueshu(int a, int b)//判断是否有大于1的最大公因数
{
  int i = 0;
  for (i = (a < b ? a : b); i >= 1; i--)
  {
    if (i == 1)
    {
      return 0;
    }
    if (a % i == 0 && b % i == 0)
    {
      return 1;
    }
  }
}
 
//四个if是以原位置为中心上下左右进行比较,注意边界位置不能数组越界
//如果某个方向上的成立,以原位置的某个方向为中心再次调用函数,即递归(裂变式反应)
//上下左右如果有在arr2中被修改为0的不进行比较,否则会产生死循环
//比如arr1[r][c]->arr1[r-1][c]->arr[r-1+1][c]
void change(int arr1[1000][1000], int arr2[1000][1000], int r, int c, int n, int m)
{
  if (gongyueshu(arr1[r][c], arr1[r][c + 1]) && c != m&&arr2[r][c+1]!=0)
  {
    arr2[r][c + 1] = 0;
    change(arr1, arr2, r, c + 1, n, m);
  }
  if (gongyueshu(arr1[r][c], arr1[r + 1][c]) && r != n && arr2[r+1][c] != 0)
  {
    arr2[r + 1][c] = 0;
    change(arr1, arr2, r + 1, c, n, m);
  }
  if (gongyueshu(arr1[r][c], arr1[r][c - 1]) && c != 0 && arr2[r][c-1] != 0)
  {
    arr2[r][c - 1] = 0;
    change(arr1, arr2, r, c - 1, n, m);
  }
  if (gongyueshu(arr1[r][c], arr1[r - 1][c]) && r != 0 && arr2[r-1][c] != 0)
  {
    arr2[r - 1][c] = 0;
    change(arr1, arr2, r - 1, c, n, m);
  }
}
 
int main()
{
  int n = 0, m = 0;
  int i = 0, j = 0;
  int r = 0, c = 0;
  int count = 0;
  int arr1[1000][1000]={ 0 };
  int arr2[1000][1000]={ 0 };
  scanf("%d %d", &n, &m);
  for (i = 0; i < n; i++)
  {
    for (j = 0; j < m; j++)
    {
      scanf("%d", &arr1[i][j]);
      arr2[i][j] = arr1[i][j];
    }
  }
//两个数组存放相同元素,arr1用来进行判断比较,arr2用来修改
//题目给出要求为正整数,所以不可能存在0,数组arr2将成立的元素修改为0,
  scanf("%d %d", &r, &c);
  arr2[r - 1][c - 1] = 0;//第r行c列在数组中的存储
  change(arr1, arr2, r - 1, c - 1, n - 1, m - 1);
 
  for (i = 0; i < n; i++)//遍历有几个0就是最大的格数
  {
    for (j = 0; j < m; j++)
    {
      if (arr2[i][j] == 0)
      {
        count++;
      }
    }
  }
  printf("%d", count);
  return 0;
}


如果出现如下报错


4e6b921ef9dc95f6cfde80e292aba957_c6655dfc4e503a2d5d3eb0f4ee8fa3ed.png


参考如下链接


VS 【】处有未经处理的异常(在【程序名】.exe 中): 0xC00000FD: Stack overflow (参数: 0x00000000,0x008D2000)。_o 0x00007ff653b82153 处有未经处理的异常(在 project1.exe 中): -CSDN博客



第十题

问题描述:

 给定一个序列 a[1], a[2], …, a[n] 和一个整数 k,请找出一个长度正好为 k 的区间,使得区间中所有数的和最大。

 即要找到一个整数 p ,使得 1 <= p 且 p+k-1 <= n ,使得 a[p]+a[p+1]+...+a[p+k-1] 最大。

输入格式:

 输入的第一行包含两个整数 n , k。

 第二行包含 n 个整数,相邻的整数之间使用一个空格分隔,表示给定的序列。

输出格式:

 输出一行包含一个整数,表示最大的区间和,你只需要输出和就行,不需要输出方案。

样例输入:

6 3

2 3 9 1 9 5

样例输出:

19

评测用例规模与约定:

 对于 30% 的评测用例,1 <= k <= n <= 30,1 <= a[i] <= 100。

 对于 60% 的评测用例,1 <= k <= n <= 1000,1 <= a[i] <= 10000。

 对于所有评测用例,1 <= k <= n <= 1000000,1 <= a[i] <= 1000000。


答案

#include<stdio.h>
int main()
{
  int a[1000000];
  int n = 0;
  int k = 0;
  int i = 0, j = 0;
  int sum = 0;
  int max = 0;
  scanf("%d%d", &n, &k);
  for (i = 0;i < n;i++)
  {
    scanf("%d", &a[i]);
  }
 
  for (i = 0;i < k;i++)
  {
    max += a[i];
  }
 
  for (i = 0;i < n - k + 1;i++)
  {
    sum = 0;
    for (j = 0;j < k;j++)
    {
      sum += a[i + j];
    }
    if (sum > max)
    {
      max = sum;
    }
  }
  printf("%d", max);
  return 0;
}
相关文章
|
6月前
|
存储 算法 C语言
C语言练习记录(蓝桥杯练习)(小蓝数点)
C语言练习记录(蓝桥杯练习)(小蓝数点)
|
存储 算法 C语言
【C语言蓝桥杯每日一题】——数字三角形
数字三角形🙌 题目描述 上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到最大的和。路径上的每一步只能从一个数走到下一层和它最近的左边的那个数或者右 边的那个数。此外,向左下走的次数与向右下走的次数相差不能超过 1。
139 0
【C语言蓝桥杯每日一题】——数字三角形
|
算法 测试技术 C语言
【C语言蓝桥杯每日一题】—— 单词分析
题目描述 小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组 成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得最多来分辨单词。 现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这 个字母出现的次数。 输入描述 输入一行包含一个单词,单词只由小写英文字母组成。 对于所有的评测用例,输入的单词长度不超过 1000。 输出描述 输出两行,第一行包含一个英文字母,表示单词中出现得最多的字母是哪 个。如果有多个字母出现的次数相等,输出字典序最小的那个。
330 0
【C语言蓝桥杯每日一题】—— 单词分析
|
C语言
C语言练级之路num5(一些蓝桥杯的小题目)
C语言练级之路num5(一些蓝桥杯的小题目)
|
C语言
蓝桥杯---等差数列(C语言)
找出5个数中两数最小之差(假定公差)
165 0
蓝桥杯---等差数列(C语言)
|
算法 C语言 C++
【C语言蓝桥杯每日一题】——排列字母
哈喽各位友友们😊,我今天又学到了很多有趣的知识,现在迫不及待的想和大家分享一下!😘我仅已此文,和大家分享【C语言蓝桥杯每日一题】——排列字母~ 都是精华内容,可不要错过哟!!!😍😍😍
142 0
|
算法 C语言 C++
【C语言蓝桥杯每日一题】——等差数列
这道题,我用到了C语言中的qsort库函数,它是一种基于快排算法思想的排序函数。首先,想让大家认识一下qsort库函数的大概样子,和如何使用。
154 0
下一篇
无影云桌面