蓝桥杯2023年真题(1)

1.分糖果

在这里插入图片描述

#include <iostream>
using namespace std;
int a = 9, b = 16, c = 7, d = 2, e = 5;
int ans = 0;
//u是当前第几个分糖果的小朋友,x和y是还剩的糖果
void dfs(int u, int x, int y){
  if(u > c){
    //如果都为0,就是已经分完了
    if(!x && !y) ans++;
    return;
  }
  for(int i = 0; i <= x; i++)
    for(int j = 0; j <= y; j++)
      if(i + j >= d && i + j <= e)
        dfs(u + 1, x - i, y - j);
}
int main()
{
  dfs(1, a, b);
  cout<<ans;
  return 0;
}

2.字母数

在这里插入图片描述

#include <iostream>
#include<vector>
using namespace std;

int f(int x){
  vector<int> v;
  int t = x;
  while(t){
    int z = t % 16;
    t /= 16;
    v.push_back(z);
  }
  for(int i = 0; i < v.size(); i++)
    if(v[i] < 10) return 0;
  return 1;
}

int main()
{
  int a = 2022, flag = 1;
  while(flag){
    a++;
    if(f(a)){
      cout<<a;
      flag = 0;
    }
  }
  return 0;
}

3.列名

在这里插入图片描述

#include <iostream>
using namespace std;
int main()
{
  int a = 26 + 26 * 26;
  for(int i = 0; i <= 25; i++){
    for(int j = 0; j <= 25; j++){
      for(int k = 0; k <= 25; k++){
        a++;
        if(a == 2022){
          cout<<char('A' + i)<<char('A' + j)<<char('A' + k);
          return 0;
        }
      }
    }
  }
  return 0;
}

4.特殊日期

在这里插入图片描述

#include <iostream>
using namespace std;
int a[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int ans = 0;

int f(int x){
  int sum = 0;
  while(x){
    sum += x % 10;
    x /= 10;
  }
  return sum;
}

int main()
{
  for(int i = 1900; i <= 9999; i++){
    if(i % 400 == 0 || (i % 4 == 0 && i % 100 != 0)) a[1] = 29;
    else a[1] = 28;
    int x = f(i);
    for(int j = 0; j < 12; j++){
      for(int k = 1; k <= a[j]; k++){
        int y = f(j + 1), z = f(k);
        if(x == y + z) ans++;
      }
    }
  }
  cout<<ans;
  return 0;
}

5.大乘积

在这里插入图片描述

#include <iostream>
using namespace std;
int a[] = {99, 22, 51, 63, 72, 61, 20, 88, 40, 21, 63, 30, 11, 18, 99, 12, 93, 16, 7, 53, 64, 9, 28, 84, 34, 96, 52, 82, 51, 77};
int ans = 0;
int main()
{
  for(int i = 0; i < 30; i++)
    for(int j = i + 1; j < 30; j++)
      if(a[i] * a[j] >= 2022) ans++;
  cout<<ans;
  return 0;
}

6.最大连通

在这里插入图片描述

#include <iostream>
using namespace std;
int hh, tt = -1;
pair<int, int> q[30 * 60];
string g[] = {
"110010000011111110101001001001101010111011011011101001111110",

"010000000001010001101100000010010110001111100010101100011110", 

"001011101000100011111111111010000010010101010111001000010100", 

"101100001101011101101011011001000110111111010000000110110000", 

"010101100100010000111000100111100110001110111101010011001011", 

"010011011010011110111101111001001001010111110001101000100011", 

"101001011000110100001101011000000110110110100100110111101011", 

"101111000000101000111001100010110000100110001001000101011001", 

"001110111010001011110000001111100001010101001110011010101110", 

"001010101000110001011111001010111111100110000011011111101010", 

"011111100011001110100101001011110011000101011000100111001011", 

"011010001101011110011011111010111110010100101000110111010110", 

"001110000111100100101110001011101010001100010111110111011011", 

"111100001000001100010110101100111001001111100100110000001101", 

"001110010000000111011110000011000010101000111000000110101101", 

"100100011101011111001101001010011111110010111101000010000111", 

"110010100110101100001101111101010011000110101100000110001010", 

"110101101100001110000100010001001010100010110100100001000011", 

"100100000100001101010101001101000101101000000101111110001010", 

"101101011010101000111110110000110100000010011111111100110010", 

"101111000100000100011000010001011111001010010001010110001010", 

"001010001110101010000100010011101001010101101101010111100101",

"001111110000101100010111111100000100101010000001011101100001", 

"101011110010000010010110000100001010011111100011011000110010", 

"011110010100011101100101111101000001011100001011010001110011", 

"000101000101000010010010110111000010101111001101100110011100", 

"100011100110011111000110011001111100001110110111001001000111", 

"111011000110001000110111011001011110010010010110101000011111", 

"011110011110110110011011001011010000100100101010110000010011", 

"010011110011100101010101111010001001001111101111101110011101"};
int cnt, ans;
int st[30][60];

void bfs(int x, int y){
  int dx[] = {0, 0, 1, -1};
  int dy[] = {1, -1, 0, 0};
  st[x][y] = 1;
  q[++tt] = make_pair(x, y);
  while(hh <= tt){
    auto it = q[hh++];
    for(int i = 0; i < 4; i++){
      int a = it.first + dx[i], b = it.second + dy[i];
      if(a < 0 || a >= 30 || b < 0 || b >= 60) continue;
      if(g[a][b] != '1') continue;
      if(st[a][b]) continue;
      cnt++;
      st[a][b] = 1;
      q[++tt] = make_pair(a, b);
    }
  }
}

int main()
{
  for(int i = 0; i < 30; i++){
    for(int j = 0; j < 60; j++){
      if(g[i][j] == '1'){
        cnt = 1;
        bfs(i, j);
        ans = max(ans, cnt);
      }
    }
  }
  cout<<ans;
  return 0;
}

7.星期几

在这里插入图片描述

#include <iostream>
using namespace std;
int main()
{
  int w, n;
  cin>>w>>n;
  while(n--){
    w++;
    if(w == 8) w = 1;
  }
  cout<<w;
  return 0;
}

8.信号覆盖

在这里插入图片描述

#include <iostream>
using namespace std;
int ans, st[200][200];
int main()
{
  int w, h, n, r;
  cin>>w>>h>>n>>r;
  int x, y;
  while(n--){
    cin>>x>>y;
    for(int i = 0; i <= w; i++){
      for(int j = 0; j <= h; j++){
        if((x - i) * (x - i) + (y - j) * (y - j) <= r * r && !st[i][j]){
          ans++;
          st[i][j] = 1;
        }
      }
    }
  }
  cout<<ans;
  return 0;
}

9.清理水域

在这里插入图片描述

10.滑行

在这里插入图片描述

#include<iostream>
#include<cstring>
using namespace std;
const int N = 200;
int g[N][N], st[N][N];
int n, m;
int ans;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

int dfs(int x, int y){
  //如果已存储过这个位置的最大值,那就返回
  if(st[x][y]) return st[x][y];
  //到最后一个点的时候才开始累加
  int res = 1;
  for(int i = 0; i < 4; i++){
    int a = x + dx[i], b = y + dy[i];
    if(a <  0 || a >= n || b < 0 || b >= m || g[a][b] >= g[x][y]) continue;
    //累加距离
    res = max(res, dfs(a, b) + 1);
  }
  //存储这个位置的最大值
  st[x][y] = res;
  return res;
}

int main(){
  cin>>n>>m;
  for(int i = 0; i < n; i++)  
    for(int j = 0; j < m; j++)
      cin>>g[i][j];
  
  for(int i = 0; i < n; i++)
    for(int j = 0; j < m; j++)
      ans = max(ans, dfs(i, j));
  cout<<ans;
  return 0;
}

11.附近最小

在这里插入图片描述

//ST表
#include<iostream>
#include<cmath>
using namespace std;
const int N = 1e6 + 10;
int n, k, a[N];
int f[N][50];

//预处理 
void pre(){
	for(int i = 1; i <= n; i++) f[i][0] = a[i];
	//以2为底,n的对数 
	int t = log(n) / log(2);
	for(int j = 1; j <= t; j++)
		for(int i = 1; i <= n - (1 << j) + 1; i++)
			f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}

int query(int l, int r){
	int k = log(r - l + 1) / log(2);
	return min(f[l][k], f[r - (1 << k) + 1][k]);
}

int main(){
  scanf("%d", &n);
	for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
	scanf("%d", &k);
	pre();
	for(int i = 1; i <= n; i++){
		int l = max(1, i - k), r = min(n, i + k);
		printf("%d ", query(l, r));
	}
	return 0;
}

//单调队列
#include<iostream>
#include<cmath>
using namespace std;
const int N = 1e6 + 10;
int q[N], hh, tt = -1; //队列存储数组下标
int n, k, a[N];


int main(){
  scanf("%d", &n);
	for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
	scanf("%d", &k);
  //扩展窗口到右边界
  int x = 1;
	for(int i = 1; i <= n; i++){
    //左边界,右边界
		int l = max(1, i - k), r = min(n, i + k);
    //处理队头下标
		if(hh <= tt && q[hh] < l) hh++;
    //处理队尾元素
    while(x <= r){
      while(hh <= tt && a[q[tt]] >= a[x]) tt--;
      q[++tt] = x;
      x++;
    }
    printf("%d ", a[q[hh]]);
	}
	return 0;
}

12.判断蓝桥

在这里插入图片描述

#include <iostream>
using namespace std;
int main()
{
  string s, t = "lanqiao";
  getline(cin, s);
  int n = s.size();
  for(int i = 0; i < n; i++){
    s[i] = tolower(s[i]);
  }
  if(s == t) printf("yes");
  else printf("no");
  return 0;
}

13.幸运数

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;

//这个数组的前一个框表示数的有多少位,后一个是表示这些数位上的数的和,数组存的值表示像这样的数在1~9999有多少个
//至于有什么用请看下面注释(4*9-->因为一个数分两半最多也就每边各4位数,其中最大也就9-->9999 9999)
int a[5][4*9];

//制作 a[5][4*9] 表,数位拆分统计
void get(int x){
  int sum=0,num=0;
  while(x){
    sum+=x%10;
    num++;
    x/=10;
  }
  a[num][sum]++;
}
int main(){

  //因为一个数是对称的,左边可以由这些数组成,右边也是一样,所以我们只需要算4位即可
  for(int i=1;i<=9999;i++){
     get(i);    
  }
  
  //利用乘法原理来统计数量
  int ans=0;
  for(int i=1;i<=4;i++)  //通过控制变量法,首先确定前半边的位数
  {
    for(int k=1;k<=i*9;k++)  //再控制他们的和-->一个两位数最多是多少(99->2*9->18)
    { 
        for(int j=1;j<=i;j++)  //最后后半边,进行变化
         {
          ans+=a[i][k]*a[j][k];
       }
    }
  }
  cout<<ans;
  return 0;
}

14.日期统计

在这里插入图片描述

#include <stdio.h>

int main() {
    int array[100] = {
        5, 6, 8, 6, 9, 1, 6, 1, 2, 4, 9, 1, 9, 8, 2, 3, 6, 4, 7, 7,
        5, 9, 5, 0, 3, 8, 7, 5, 8, 1, 5, 8, 6, 1, 8, 3, 0, 3, 7, 9,
        2, 7, 0, 5, 8, 8, 5, 7, 0, 9, 9, 1, 9, 4, 4, 6, 8, 6, 3, 3,
        8, 5, 1, 6, 3, 4, 6, 7, 0, 7, 8, 2, 7, 6, 8, 9, 5, 6, 5, 6,
        1, 4, 0, 1, 0, 0, 9, 4, 8, 0, 9, 1, 2, 8, 5, 0, 2, 5, 3, 3
    };

    int daysInMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int ans = 0;

    for (int month = 1; month <= 12; ++month) {
        for (int day = 1; day <= daysInMonth[month]; ++day) {
            int dateSeq[8] = {2, 0, 2, 3, month / 10, month % 10, day / 10, day % 10};
            int k = 0;

            for (int i = 0; i < 100; ++i) {
                if (array[i] == dateSeq[k]) {
                    ++k;
                    if (k == 8) {
                        ans++;
                        break;
                    }
                }
            }
        }
    }

    printf("%d\n", ans);
    return 0;
}

15.求和

在这里插入图片描述

#include <iostream>
using namespace std;
int main()
{
  cout<<1ll * 20230409 * 20230408 / 2;
  return 0;
}

16.工作时长

在这里插入图片描述

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> v;
int a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main()
{
  int year, month, day, h, m, s;
  while(scanf("%d-%d-%d %d:%d:%d", &year, &month, &day, &h, &m, &s) != EOF){
    long long sum = 0;
    for(int i = 1; i < month; i++)
      sum += a[i];
    sum *= 24 * 60 * 60;
    sum += day * 24 * 60 * 60;
    sum += h * 60 * 60;
    sum += m * 60;
    sum += s;
    v.push_back(sum);
  }
  long long ans = 0;
  sort(v.begin(), v.end());
  for(int i = 1; i < v.size(); i++){
    ans += v[i] - v[i - 1];
    i++;
  }
  cout<<ans;
  return 0;
}

17.2023

在这里插入图片描述

#include <iostream>
using namespace std;
int main()
{
  int x = 12345678, y = 98765432, ans = 0;
  for(int i = x; i <= y; i++){
    string s = to_string(i);
    //找第一次出现的位置 
    int a = s.find('2');
    if(a == -1) continue;
    //从a+1位置开始截取到结尾 
    s = s.substr(a + 1);
    a = s.find('0');
    if(a == -1) continue;
    s = s.substr(a + 1);
    a = s.find('2');
    if(a == -1) continue;
    s = s.substr(a + 1);
    a = s.find('3');
    if(a == -1) continue;
    ans++;
  }
  ans = y - x + 1 - ans;
  cout<<ans;
  return 0;
}

18.有奖问答

在这里插入图片描述

//dfs
#include <iostream>
using namespace std;
int ans = 0;

void dfs(int u, int sum){
  if(u > 30 || sum == 100) return;
  if(sum == 70) ans++;

  //错了 
  dfs(u + 1, 0);
  //对了 
  dfs(u + 1, sum + 10);
}

int main()
{
  //一开始可以选答或不答 
  dfs(0, 0);
  cout<<ans;
  return 0;
}

//dp
#include <iostream>
using namespace std;
int f[40][110]; //f[i][j]: 做了i题,获得了j分的方案数
int res;

int main()
{
  f[1][0] = f[1][10] = 1;
  for(int i = 2; i <= 30; i++){
    for(int j = 0; j <= 100; j += 10){
      //如果没有分了,说明之前错了一题或者没做
      if(!j)
        for(int k = 0; k <= 90; k += 10)
          f[i][j] += f[i - 1][k];
      else
        f[i][j] = f[i - 1][j - 10];
      //如果已经有70分,那就累加所有情况
      if(j == 70) res += f[i][j];
    }
  }
  cout<<res;
  return 0;
}

19.01串的熵

在这里插入图片描述

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
  int n = 23333333, ans;
  for(int i = 0; i <= n; i++){
    double a = i, b = n - i; 
    double sum = -1 * a / n * log2(a / n) * a - 1 * b / n * log2(b / n) * b;
    if(abs(sum - 11625907.5798) < 0.0001) ans = min(a, b);
  }
  cout<<ans;
  return 0;
}

20.幸运数字

在这里插入图片描述

#include <iostream>
#include <vector>
using namespace std;

int f(int x, int z){
  vector<int> v;
  int sum = 0, t = x;
  while(t){
    v.push_back(t % z);
    t /= z;
  }
  for(int i = 0; i < v.size(); i++) sum += v[i];
  if(x % sum == 0) return 1;
  else return 0;
}

int main()
{
  int res = 0, x = 0;
  while(res != 2023){
    x++;
    if(f(x, 2) && f(x, 10) && f(x, 8) && f(x, 16)) res++;
  }
  cout<<x;
  return 0;
}

21.阶乘求和

在这里插入图片描述
1到50阶乘列表

格式:⾃然数,值位数,值

1 ,1 ,1

2 ,1 ,2

3 ,1 ,6

4 ,2 ,24

5 ,3 ,120

6 ,3 ,720

7 ,4 ,5040

8 ,5 ,40320

9 ,6 ,362880

10 ,7 ,3628800

11 ,8 ,39916800

12 ,9 ,479001600

13 ,10 ,6227020800

14 ,11 ,87178291200

15 ,13 ,130********00

16 ,14 ,20922789888000

17 ,15 ,355687428096000

18 ,16 ,6402373705728000

19 ,18 ,121645*********000

20 ,19 ,2432902008176640000

21 ,20 ,51090942171709440000

22 ,22 ,1124000727777607680000

23 ,23 ,25852016738884976640000

24 ,24 ,620448401733239439360000

25 ,26 ,155********330985984000000

26 ,27 ,403291461126605635584000000

27 ,29 ,10888869450418352160768000000

28 ,30 ,304888344611713860501504000000

29 ,31 ,8841761993739701954543616000000

30 ,33 ,265252859812191058636308480000000

31 ,34 ,8222838654177922817725562880000000

32 ,36 ,263130836933693530167218012160000000

33 ,37 ,8683317618811886495518194401280000000

34 ,39 ,295232799039604140847618609643520000000

35 ,41 ,10333147966386144929666651337523200000000

36 ,42 ,371993326789901217467999448150835200000000

37 ,44 ,137********226345046315979581580902400000000

38 ,45 ,523022617466601111760007224100074291200000000

39 ,47 ,20397882081197443358640281739902897356800000000

40 ,48 ,815915283247897734345611269596115894272000000000

41 ,50 ,33452526613163807108170062053440751665152000000000

42 ,52 ,1405006117752879898543142606244511569936384000000000

43 ,53 ,60415263063373835637355132068513997507264512000000000

44 ,55 ,2658271574788448768043625811014615890319638528000000000

45 ,57 ,119622220865480194561963161495657715064383733760000000000

46 ,58 ,5502622159812088949850305428800254892961651752960000000000

47 ,60 ,258623241511168180642964355153611979969197632389120000000000

48 ,62 ,12413915592536072670862289047373375038521486354677760000000000

49 ,63 ,608281864034267560872252163321295376887552831379210240000000000

50 ,65 ,30414093201713378043612608166064768844377641568960512000000000000

//前面40!已经有9个零了,里面包含9个2 * 5,所以只用计算到40!
#include <iostream>
using namespace std;
const int mod = 1e9;

int main()
{
  long long sum = 0, res = 1;
  for(int i = 1; i <= 40; i++){
    res = res * i % mod;
    sum = (sum + res) % mod;
  }
  cout<<sum;
  return 0;
}
  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值