蓝桥杯第二天刷题

题目一:奇数倍数

题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
请你找到最小的整数 X 同时满足:
X 是 2019 的整倍数;
X 的每一位数字都是奇数。
运行限制
最大运行时间:1s
最大运行内存: 128M

暴力枚举倍数,检查是否每位为奇数

#include <iostream>
using namespace std;

bool check(int x){
  while(x){
    int ans = x % 10;
    x /= 10;
    if(ans % 2 == 0) return false;
  }
  return true;
}

int main()
{
  for(int i = 1; i <= 1000; i++){
    int x = 2019 * i;
    if(check(x)){
      cout<<x<<endl;
      break;
    }
  }
  return 0;
}

题目二:求值

题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
学习了约数后,小明对于约数很好奇,他发现,给定一个正整数 t,总是可以找到含有 t 个约数的整数。小明对于含有 t 个约数的最小数非常感兴趣,并把它定义为 S t
例如 S 1 =1,S 2 =2,S 3 =4,S 4 =6,⋅⋅⋅ 。
现在小明想知道,当 t=100 时,S t 是多少?即S 100 是多少?
运行限制
最大运行时间:1s
最大运行内存: 128M

考数学,根据“约数个数定理” 100=2* 2* 5 *5 最小为:2^(5-1)*3^(5-1)*5^(2-1)*7^(2-1)

例题:正整数378000共有多少个正约数

解:将378000分解质因数378000=24×33×53×71

由约数个数定理可知378000共有正约数(4+1)×(3+1)×(3+1)×(1+1)=160个。

#include <iostream>
using namespace std;
int main()
{
  printf("%lld",16*81*35);
  return 0;
}

题目三:求和

问题描述
给定 n 个整数a 1 ,a 2 ,⋅⋅⋅,a n ,求它们两两相乘再相加的和,即:
S=a 1 a 2 +a 1 a 3 +⋯+a 1 a n +a 2 a 3 +⋯+a n−2 a n−1 +a n−2 a n +a n−1 a n
输入格式
输入的第一行包含一个整数 n
第二行包含 n 个整数 a 1 ,a 2 ,⋯,a n
输出格式
输出一个整数 S,表示所求的和。请使用合适的数据类型进行运算。
样例输入
4
1 3 6 9
样例输出
117
数据范围
1≤n≤200000,1≤a i ≤1000 。

每个数乘以后面所以数的和,数组区间和用前缀和来写

假设有四个数,即是 a[1] * (s[4] - s[1]), a[2]*(s[4]-s[2]), .....

注意数据范围,n*ai > int,爆范围

#include<iostream>
using namespace std;

typedef long long LL;
const int N = 200010;
int n;
int a[N];
LL s[N];

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

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

  LL ans = 0;
  for(int i = 1; i <= n; i++){
    ans += a[i] * (s[n] - s[i]);
  }
  cout<<ans<<endl;
  return 0;
}

题目四:数位排序

问题描述
小蓝对一个数的数位之和很感兴趣, 今天他要按照数位之和给数排序。当 两个数各个数位之和不同时, 将数位和较小的排在前面, 当数位之和相等时, 将数值小的排在前面。
例如, 2022 排在 409 前面, 因为 2022 的数位之和是 6, 小于 409 的数位 之和 13 。
又如, 6 排在 2022 前面, 因为它们的数位之和相同, 而 6 小于 2022 。
给定正整数 n,m, 请问对 1 到 n 采用这种方法排序时, 排在第 m 个的元 素是多少?
输入格式
输入第一行包含一个正整数 n
第二行包含一个正整数 m
输出格式
输出一行包含一个整数, 表示答案。
样例输入
13
5
样例输出
3

先按照数位之和排序,再按照值大小排序,这不就是pair吗

求数位和,和值一起放进pair里面,再排序

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

const int N = 1e6 + 10;
typedef pair<int, int> PII;
int n, m;
PII a[N];

int weihe(int x){
  int ans = 0;
  while(x){
    ans += x % 10;
    x /= 10;
  }
  return ans;
}

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

  for(int i = 1; i <= n; i++){
    int x = weihe(i);
    a[i] = {x, i};
  }
  sort(a + 1, a + 1 + n);

  cout<<a[m].second<<endl;
  return 0;
}

题目五:回文日期

题目描述
2020 年春节期间,有一个特殊的日期引起了大家的注意:2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202,恰好是一个回文数。我们称这样的日期是回文日期。
有人表示 20200202 是 “千年一遇” 的特殊日子。对此小明很不认同,因为不到 2 年之后就是下一个回文日期:20211202 即 2021 年 12 月 2 日。
也有人表示 20200202 并不仅仅是一个回文日期,还是一个 ABABBABA 型的回文日期。对此小明也不认同,因为大约 100 年后就能遇到下一个 ABABBABA 型的回文日期:21211212 即 2121 年 12 月 12 日。算不上 “千年一遇”,顶多算 “千年两遇”。
给定一个 8 位数的日期,请你计算该日期之后下一个回文日期和下一个 ABABBABA 型的回文日期各是哪一天。
输入描述
输入包含一个八位整数 N,表示日期。
对于所有评测用例,10000101≤N≤89991231,保证 N 是一个合法日期的 8 位数表示。
输出描述
输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。
输入输出样例
输入
20200202
输出
2021120221211212

思路就是暴力枚举,从该日期开始的所有日期,判断日期是否合法,以及满足条件

设置了两个值,保证只输出第一个出现的

但是题目数据有点傻了吧唧,N的范围题目写89991231,只能过90%

改成999999999,才过

#include <iostream>
using namespace std;

bool isleap(int year){
  return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}

bool check(int year, int month, int day){
  if(month > 12 || month == 0) return false;
  if(day > 31) return false;
  if(month == 2){
    if(isleap(year) && day > 29)  return false;
    if(!isleap(year) && day > 28) return false;
  }
  if(month == 4 || month == 6 || month == 9 || month == 11)
    if(day > 30) return false;
  return true;
}

int main()
{
  int a, b, c, d, e, f, g, h, n;
  int year, month, day;
  scanf("%d", &n);

  int ans = 0, res = 0;
  for(int i = n ; i <= 99999999; i++){
    int year = i / 10000;
    int month = (i % 10000) / 100;
    int day = i % 100;
    a = i / 10000000;
    b = i / 1000000 % 10;
    c = i / 100000 % 10;
    d = i / 10000 % 10;
    e = i / 1000 % 10;
    f = i / 100 % 10;
    g = i / 10 % 10;
    h = i % 10;
    if(a == h && b == g && c == f && d == e)
      if(check(year, month, day) && ans == 0){
        ans = i;
      }
    if(a == h && b == g && c == f && d == e && a == c && f == h && b == d && e == g)
      if(check(year, month, day) && res == 0) {
        res = i;
      }
  }
  cout<<ans<<endl<<res<<endl;
  return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Libert_AC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值