蓝桥杯夺奖班 | 五千字搞定模拟题(下)

目录

纸张尺寸

问题描述

输入格式

输出格式

样例输入1

样例输出1

样例输入 2

样例输出 2

运行限制

AC_Code

排列字母

问题描述

运行限制

解题思路

AC_Code

数位排序

问题描述

输入格式

输出格式

样例输入

样例输出

样例说明

评测用例规模与约定

运行限制

解题思路

AC_Code

数字反转

题目描述

输入描述

输出描述

输入输出样例

运行限制

AC_Code

解法 1 字符串

解法 2 反转整数

        ISBN 号码

题目描述

输入描述

输出描述

输入输出样例

思路

AC 代码

解法 1 朴素解法

        天干地支

题目描述

输入描述

输出描述

输入输出样例

思路

AC 代码


纸张尺寸

问题描述

在 ISO 国际标准中定义了 A0 纸张的大小为 1189mm ×× 841mm, 将 A0 纸 沿长边对折后为 A1 纸, 大小为 841mm ×× 594mm, 在对折的过程中长度直接取 下整 (实际裁剪时可能有损耗)。将 A1 纸沿长边对折后为 A2 纸, 依此类推。

输入纸张的名称, 请输出纸张的大小。

输入格式

输入一行包含一个字符串表示纸张的名称, 该名称一定是 A0、A1、A2、 A3、A4、A5、A6、A7、A8、A9 之一。

输出格式

输出两行,每行包含一个整数,依次表示长边和短边的长度。

样例输入1

A0

样例输出1

1189
841

样例输入 2

A1

样例输出 2

841
594

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 512M

AC_Code

#include
using namespace std;

int main()
{
  char c; int x;
  cin >> c >> x ;
  int a = 1189,b = 841;
  while(x --)
  {
      a /= 2;
      if(a < b)  swap(a , b);
  }
  cout << a << endl;
  cout << b << endl;

  return 0;
}

排列字母

问题描述

本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。

小蓝要把一个字符串中的字母按其在字母表中的顺序排列。

例如,LANQIAO 排列后为 AAILNOQ。

又如,GOODGOODSTUDYDAYDAYUP 排列后为 AADDDDDGGOOOOPSTUUYYY。

请问对于以下字符串,排列之后字符串是什么?

WHERETHEREISAWILLTHEREISAWAY

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 512M

解题思路

利用sort函数直接进行排序

AC_Code

#include 
#include
using namespace std;
int main()
{
  string s = "WHERETHEREISAWILLTHEREISAWAY";
  sort(s.begin(),s.end());
  cout << s << endl;
  return 0;
}

数位排序

问题描述

小蓝对一个数的数位之和很感兴趣, 今天他要按照数位之和给数排序。当 两个数各个数位之和不同时, 将数位和较小的排在前面, 当数位之和相等时, 将数值小的排在前面。

例如, 2022 排在 409 前面, 因为 2022 的数位之和是 6, 小于 409 的数位 之和 13 。

又如, 6 排在 2022 前面, 因为它们的数位之和相同, 而 6 小于 2022 。

给定正整数 n,m, 请问对 1 到 n 采用这种方法排序时, 排在第 m 个的元 素是多少?

输入格式

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

第二行包含一个正整数 m 。

输出格式

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

样例输入

13
5

样例输出

3

样例说明

1 到 13 的排序为: 1,10,2,11,3,12,4,13,5,6,7,8,9。第 5 个数为 3 。

评测用例规模与约定

对于 30% 的评测用例, 1≤m≤n≤300 。

对于 50% 的评测用例,1≤m≤n≤1000 。

对于所有评测用例, 1 m≤n≤106 。

运行限制

  • 最大运行时间:3s
  • 最大运行内存: 512M

解题思路

首先取每个数的数位和,然后直接用sort快排进行排序,注意排序的两个条件,写一个cmp函数自定义sort函数

AC_Code

#include 
using namespace std;

const int N = 1e6 + 10;
int a[N],b[N];

bool cmp(int x,int y)
{
  //直接按照数位和从小到大排序即可
  //数位和相等按照x,y数值进行从小到大排序
  return b[x] < b[y] || b[x] == b[y] && x < y;
}

int main()
{
  int n, m;
cin >> n >> m;
for(int i = 1;i <= n; i ++)
{
  int num = i;
  //取数位和
  while(num){
    b[i] += num % 10;
    num /= 10;
  }
  a[i] = i;
}
sort(a+1, a+1+n, cmp);
cout << a[m] << endl;
  return 0;
}

数字反转

题目描述

给定一个整数,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见实例 2)。

输入描述

蓝桥杯夺奖班 | 五千字搞定模拟题(下)_第1张图片

输出描述

输出共 1 行,一个整数,表示反转后的新数。

输入输出样例

示例 1

输入

123

输出

321

示例 2

输入

-380

输出

-83

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

AC_Code

解法 1 字符串

字符串反转可以使用 reverse 函数,但是需要手动删除前导00。

#include 
#include 
#include 

using namespace std;

int main()
{
    string s;
    cin >> s;
    bool is_minus = s[0] == '-';
    //  标记是否为负数
    if (is_minus)
        s.erase(s.begin());
    reverse(s.begin(), s.end());
    //  反转字符串
    int k = 0;
    while (k + 1 < s.size() && s[k] == '0')
        k ++;
    if (is_minus)
        cout << '-';
    cout << s.substr(k) << endl;
    return 0;
}

解法 2 反转整数

整数做法相对字符串做法不需要清理前导00,因为当原整数末尾有00时, ×10×10 结果还为 00。

#include 
using namespace std;
int main()
{
  int n;
  cin >> n;

  int sum = 0;
  while(n)
  {
    sum = sum * 10 + n%10;
    n /= 10;
  }

  cout << sum << endl;
  return 0;
}

ISBN 号码

题目描述

每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 9 位数字、1 位识别码和 3 位分隔符,其规定格式如 “x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位是识别码,例如 0-670-82162-4 就是一个标准的 ISBN 码。ISBN 码的首位数字表示书籍的出版语言,例如 0 代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如 670 代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。

识别码的计算方法如下:

首位数字乘以 1 加上次位数字乘以 2 …… 以此类推,用所得的结果 mod 11,所得的余数即为识别码,如果余数为 10,则识别码为大写字母 X。例如 ISBN 号码 0-670-82162-4 中的识别码 4 是这样得到的:对 067082162 这 9 个数字,从左至右,分别乘以 1,2,…,9,再求和,即 0×1+6×2+……+2×9=158,然后取 158 mod 11 的结果 4 作为识别码。 你的任务是编写程序判断输入的 ISBN 号码中识别码是否正确,如果正确,则仅输出 Right;如果错误,则输出你认为是正确的 ISBN 号码。

输入描述

输入一行,是一个字符序列,表示一本书的 ISBN 号码(保证输入符合 ISBN 号码的格式要求)。

输出描述

输出一行,假如输入的 ISBN 号码的识别码正确,那么输出 Right,否则,按照规定的格式,输出正确的 ISBN 号码(包括分隔符“-”)。

输入输出样例

示例 1

输入

0-670-82162-4

输出

Right

示例 2

输入

0-670-82162-0

输出

0-670-82162-4

思路

题意

根据题中给的规则,计算出识别码,验证此 ISBN 码是否正确

  1. 正确输出 Right;
  2. 错误则输出正确的 ISBN 码;

首先,最容易想到得就是用 c 语言的 scanf 函数 scanf("%c-%c%c%c-%c%c%c%c%c-%c",…………) 不可以?可以!相当可以,在真正比赛的时候是不太容易想到最好的最优雅的写法的,然而能 AC 就是好代码,只是这样写很麻烦。

需要注意的地方

  1. 注意题目是要求输入Yes,yes,Right,right,True,true中的哪一个,是首字母大写,还是全大写,还是全小写。
  2. 最后一位数为 10 的时候,是'X'还是'x'。
  3. 类似的题目还有身份证的验证。

AC 代码

解法 1 朴素解法

#include 
#include 
#include 

using namespace std;

int main()
{
    char a[10];
    scanf("%c-%c%c%c-%c%c%c%c%c-%c", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9]);
    int res = 0;
    for (int i = 0; i < 9; i ++ )
        res += (a[i] - '0') * (i + 1);
    res %= 11;
    if (res == 10 && a[9] == 'X' || a[9] - '0' == res)
        puts("Right");
    else{
        if (res == 10)
            a[9] = 'X';
        else
            a[9] = '0' + res;
        printf("%c-%c%c%c-%c%c%c%c%c-%c\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]);
    }

    return 0;
}

解法 2 优雅写法

先读入字符串,处理除了最后一个字符外的所有字符,若为'-',则指针往后走,反之乘 k 加入 res。

#include 
#include 
#include 

using namespace std;

int main()
{
    string s;
    cin >> s;
    int res = 0, k = 1;
    for (int i = 0; i + 1 < s.size(); ++ i )
        if (s[i] != '-')
            res += (s[i] - '0') * k, k ++;
    res %= 11;

    char c = 'X';
    if (res < 10)
        c = res + '0';

    if (s.back() == c)
        puts("Right");
    else{
        s.back() = c;
        cout << s << endl;
    }
    return 0;
}

天干地支

题目描述

古代中国使用天干地支来记录当前的年份。

天干一共有十个,分别为:甲(jiǎ)、乙(yǐ)、丙(bǐng)、丁(dīng)、戊(wù)、己(jǐ)、庚(gēng)、辛(xīn)、壬(rén)、癸(guǐ)。

地支一共有十二个,分别为:子(zǐ)、丑(chǒu)、寅(yín)、卯(mǎo)、辰(chén)、巳(sì)、午(wǔ)、未(wèi)、申(shēn)、酉(yǒu)、戌(xū)、 亥(hài)。

将天干和地支连起来,就组成了一个天干地支的年份,例如:甲子。

2020 年是庚子年。

每过一年,天干和地支都会移动到下一个。例如 2021 年是辛丑年。

每过 60 年,天干会循环 6 轮,地支会循环 5 轮,所以天干地支纪年每 60 年轮回一次。例如 1900 年,1960 年,2020 年都是庚子年。

给定一个公元纪年的年份,请输出这一年的天干地支年份。

输入描述

输入一行包含一个正整数,表示公元年份。

其中有 ,输入的公元年份为不超过 9999 的正整数。

输出描述

输入一行包含一个正整数,表示公元年份。

输入输出样例

示例

输入

2020

输出

gengzi

思路

首先毋庸置疑是需要求出 0000 年是什么年,由题意得 2020 年为庚子年,且 60 年为一个大循环,即 1960 和 2080 均为庚子年,同理可得 0040 年为庚子年(0040+60*31=2020) 根据 0040 年为庚子年我们可以得出:

  1. 天干每 10 年为一个循环,所以 0000 年为庚 x 年;
  2. 地支 12 年一个循环所以 0004 为 x 子年,0003 为 x 亥年,0002 为 x 戌年,0001 为 x 酉年,0000 年 x 申年。

综上所述,0000 年为庚申年,此时,我们打表可以按照天干庚为第一个,地支申为第一个,进行打表。另外这题打表不要敲错字符哦~

AC 代码

#include 
#include 
#include 

using namespace std;

string tiangan[] = {
    "geng", "xin", "ren", "gui", "jia", "yi", "bing", "ding", "wu", "ji"
}, dizhi[] = {
    "shen", "you", "xu", "hai", "zi", "chou", "yin", "mao", "chen", "si", "wu", "wei"
};

int main()
{
    int n;
    cin >> n;
    cout << tiangan[n % 10] << dizhi[n % 12] << endl;
    return 0;
}

 

你可能感兴趣的:(百日算法竞赛,#,刷题,#,蓝桥杯周训练,蓝桥杯,职场和发展)