蓝桥杯真题打卡第三天

第一题:门牌号

题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小蓝要为一条街的住户制作门牌号。
这条街一共有 2020位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7即需要 1 个字符 0,2个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?
运行限制
最大运行时间:1s
最大运行内存: 128M

暴力枚举从 1 - 2020

#include
using namespace std;

int check(int x){
  int res = 0;
  while(x){
    int t = x % 10;
    x /= 10;
    if(t == 2) res++;
  }
  return res;
}

int main(){
  int ans = 0;
  for(int i = 1; i <= 2020; i++){
    ans += check(i);
  }

  cout<

第二题:货物摆放

题目描述
小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有 n 箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、宽、高。
小蓝希望所有的货物最终摆成一个大的长方体。即在长、宽、高的方向上分别堆 LWH 的货物,满足 n=L×W×H
给定 n,请问有多少种堆放货物的方案满足要求。
例如,当 n=4 时,有以下 66 种方案:1×1×4、1×2×2、1×4×1、2×1×2、2×2×1、4×1×11×1×4、1×2×2、1×4×1、2×1×2、2×2×1、4×1×1。
请问,当 n=2021041820210418 (注意有 16 位数字)时,总共有多少种方案?
提示:建议使用计算机编程解决问题。
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
运行限制
最大运行时间:1s
最大运行内存: 256M

相当于求n的质因子,然后排列,看有多少种

实际上可以知道,通过暴力枚举,很多数是不必要枚举的,所以直接求n的质因数

再枚举n的质因数

#include
#include
#include
using namespace std;

typedef long long LL;
vector a;

int main(){
  LL n = 2021041820210418;
  
  //找出所有质因子
  for(LL i = 1; i * i <= n; i++){
    if(n % i == 0){
      a.push_back(i);
      if(n / i != i) 
        a.push_back(n / i);
    } 
  }

  LL ans = 0;
  for(auto x : a)
    for(auto y : a)
      for(auto z : a)
        if(x * y * z == n) ans++;

  cout<

第三题

题目描述
小蓝在一个 nm 列的方格图中玩一个游戏。
开始时,小蓝站在方格图的左上角,即第 11 行第 11 列。
小蓝可以在方格图上走动,走动时,如果当前在第 r 行第 c 列,他不能走到行号比 r 小的行,也不能走到列号比 c 小的列。同时,他一步走的直线距离不超过 3。
例如,如果当前小蓝在第 3 行第 5 列,他下一步可以走到第 3行第 6 列、第 3 行第 7 列、第 3 行第 8 列、第 4 行第 5 列、第 4 行第 6 列、第 4 行第 7 列、第 5 行第 5 列、第 5 行第 6 列、第 6 行第 5 列之一。
小蓝最终要走到第 n 行第 m 列。
在图中,有的位置有奖励,走上去即可获得,有的位置有惩罚,走上去就要接受惩罚。奖励和惩罚最终抽象成一个权值,奖励为正,惩罚为负。
小蓝希望,从第 11 行第 11 列走到第 n 行第 m 列后,总的权值和最大。请问最大是多少?
输入描述
输入的第一行包含两个整数 n,m,表示图的大小。
接下来 n 行,每行 m 个整数,表示方格图中每个点的权值。
其中,1≤n≤100,−10 4 ≤权值≤10 4
输出描述
输出一个整数,表示最大权值和。
输入输出样例
示例 1
输入
3 5
-4 -5 -10 -3 1
7 5 -9 3 -10
10 -2 6 -10 -4
输出
15

简单dp

f[i, j] 表示跳跃到i,j位置是最大的权值

是从九个状态里面跳进来的,所以枚举九个状态,取最大值

#include
#include
using namespace std;

const int N = 110;
int a[N][N], f[N][N];
int n ,m;
const int dx[] = {0, 0, 0, 1, 1, 1, 2, 2, 3};
const int dy[] = {1, 2, 3, 0, 1, 2, 0, 1, 0};

int main(){
  scanf("%d%d", &n, &m);

  for(int i = 1; i <= n; i++)
    for(int j = 1; j <= m; j++)
      scanf("%d", &a[i][j]);

  memset(f, -0x3f, sizeof f);
  f[1][1] = a[1][1];
  for(int i = 1; i <= n; i++)
    for(int j = 1; j <= m; j++)
      for(int k = 0; k < 9; k++){
        int x = i - dx[k], y = j - dy[k];
        if(x < 0 || x > n || y < 0 || y > m) continue;
        f[i][j] = max(f[i][j], f[x][y] + a[i][j]);
      }

  cout<

第四题:重新排序

问题描述
给定一个数组 A 和一些查询 L i ,R i , 求数组中第L i 至第 R i 个元素之和。
小蓝觉得这个问题很无聊, 于是他想重新排列一下数组, 使得最终每个查 询结果的和尽可能地大。小蓝想知道相比原数组, 所有查询结果的总和最多可 以增加多少?
输入格式
输入第一行包含一个整数 n
第二行包含 n 个整数 A 1 ,A 2 ,⋯,A n , 相邻两个整数之间用一个空格分隔。
第三行包含一个整数 m 表示查询的数目。
接下来 m 行, 每行包含两个整数 L i R i , 相邻两个整数之间用一个空格分 隔。
输出格式
输出一行包含一个整数表示答案。

样例输入

5
1 2 3 4 5
2
1 3
2 5

样例输出

4

统计出现频率,使得最大数出现的频率最大,然后相乘再相加

这道题要转一下思想,转一下就好理解了

#include
#include
using namespace std;

typedef long long LL;
const int N = 100010;
LL a[N], s[N], g[N];
int n, m;
LL olds, news;

int main(){
  scanf("%d", &n);

  for(int i = 1; i <= n; i++){
    scanf("%lld", &a[i]);
    s[i] = s[i - 1] + a[i];
  }

  scanf("%d", &m);
  while(m --){
    int l, r;
    scanf("%d%d", &l, &r);
    g[l] ++, g[r + 1] --;
    olds += s[r] - s[l - 1];
  }

  for(int i = 1; i <= n; i++)
    g[i] += g[i - 1];

  sort(a + 1, a + 1 + n);
  sort(g + 1, g + 1 + n);
  int i = n;
  while(g[i] != 0){
    news += g[i] * a[i];
    i--;
  }

  cout<

你可能感兴趣的:(蓝桥杯集训,蓝桥杯,java,职场和发展)