第三章:编程基础通关2 - 枚举与单位换算 枚举2

枚举2

目录

枚举2

第一题 卡片

         题目描述

运行限制

第二题 直线

题目描述

运行限制

第三题 回文日期

题目描述

输入描述

输出描述

输入输出样例

运行限制

第四题 合法日期

题目描述

输入描述

输出描述

输入输出样例

运行限制

第五题 特别数的和

题目描述

输入描述

输出描述

输入输出样例

第六题 猴子分香蕉

题目描述

运行限制


第一题 卡片

题目描述

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

小蓝有很多数字卡片,每张卡片上都是数字 0 到 9。

小蓝准备用这些卡片来拼一些数,他想从 1 开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。

小蓝想知道自己能从 1 拼到多少。

例如,当小蓝有 30 张卡片,其中 0到 9 各 3 张,则小蓝可以拼出 1 到 10,

但是拼 1时卡片 1 已经只有一张了,不够拼出 11。

现在小蓝手里有 0 到 9 的卡片各 2021 张,共 20210张,请问小蓝可以从 1拼到多少?

提示:建议使用计算机编程解决问题。

运行限制

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

#include <iostream>
using namespace std;
int num[10];
int main()
{
  for(int i=0;i<10;i++) num[i]=2021;
  int ans =1;
  while(true){
    int x =ans;
    while(x){
      int now = x% 10;
      if(num[now] >0) num[now]--;
      else break;
      x/=10;
    }
    if(x) break;
    ans++;
  }
  cout << ans -1 <<endl;
	return 0;
}

数组赋值,用for循环。

第二题 直线

题目描述

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

在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上, 那么这些点中任意两点确定的直线是同一条。

给定平面上 2 × 3 个整点{(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z}(x,y)∣0≤x<2,0≤y<3,x∈Z,y∈Z​,即横坐标 是 0 到 1 (包含 0 和 1) 之间的整数、纵坐标是 0 到 2 (包含 0 和 2) 之间的整数 的点。这些点一共确定了 11 条不同的直线。

给定平面上 20 × 2120×21 个整点 {(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z}(x,y)∣0≤x<20,0≤y<21,x∈Z,y∈Z,即横 坐标是 0 到 19 (包含 0 和 19) 之间的整数、纵坐标是 0到 20 (包含 0和 20​) 之 间的整数的点。

请问这些点一共确定了多少条不同的直线。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M
#include <bits/stdc++.h>
using namespace std;
struct Point{
    double x,y;
}p[25*25];
map<pair<double,double>,int> line;//pair 存斜率k和截距b,表示直线line

int main()
{
    int cnt = 0;
    int col = 20,row = 21;
    for (int i=0;i<row;i++)
        for(int j=0;j<col;j++){
            p[cnt].x = i;
            p[cnt++].y = j; //先p[cnt].y=j,后再cnt++
        }
    int linenum = row + col;
    for (int i=0;i<cnt;i++)
        for (int j=0;j<cnt;j++){
            if(p[i].x == p[j].x || p[i].y==p[j].y)
                continue;
            double k=(p[j].y-p[i].y)/(p[j].x-p[i].x);
            double b=(p[j].x*p[i].y-p[i].x*p[j].y)/(p[j].x-p[i].x);
            if(line[{k,b}]==0){
                line[{k,b}]=1;
                linenum++;
                
            }
        }
        cout <<linenum<<endl;
    return 0;
}

点斜式。y=kx+b

1.map的value默认值
在使用map的[]操作符对其进行访问时,如果map中尚没有查询的key值,则将创建一个新的键值对。其key值为查询的值,value值分为以下两种情况:
value为内置类型时,其值将被初始化为0
value为自定义数据结构时,如果定义了默认值则初始化为默认值,否则初始化为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,表示日期。

输出描述

输出两行,每行 1 个八位数。第一行表示下一个回文日期,第二行表示下一个 ABABBABA 型的回文日期。

输入输出样例

示例

输入

20200202

输出

20211202
21211212

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int D[13] = {-1,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool checkLeapYear(int y){
  if(y%400==0||(y%4==0 && y%100!=0)) return true;
  return false;
}
bool checkABABBABAstyle(string s){
  if(s[0]==s[2]&&s[0]==s[5]&&s[0]==s[7]&&s[1]==s[3]&&s[1]==s[4]&&s[1]==s[6])
    return true;
  return false;
}

int main()
{
  string S,ans1="",ans2="";
  string s,t,year;
  int y,m,d,i;
  cin >>S;
  year=S.substr(0,4); //从第0位置开始,拿走4个
  for (i=stoi(year);ans1==""||ans2=="";i++)//stoi转换成数值
  {
    s = to_string(i);
    t = to_string(i);
    reverse(t.begin(),t.end());
    s+=t; //8位 利用四位的年,构造出来的回文,
    if(s<=S) continue;//20211202
    y = stoi(s.substr(0,4)),m=stoi(s.substr(4,2)),d=stoi(s.substr(6,2));
    if(checkLeapYear(y)) D[2] = 29;else D[2]=28;
    if(m<1 || m>12) continue;
    if(d<1 || d>D[m]) continue;
    if(ans1 =="") ans1 = s;
    if(checkABABBABAstyle(s) && ans2=="") ans2 = s;
  }
  cout <<ans1<<endl<<ans2<<endl;
  // 请在此输入您的代码
  return 0;
}

stoi 字符串转为整型;

substr(0,4)从字符串0位开始,数四个字符,拿走赋值

reverse(t.begin(),t.end()),字符串翻转,首地址和尾地址

第四题 合法日期

题目描述

小蓝正在上小学,老师要求同学们在暑假每天记日记。可是小蓝整个暑假都在玩,直到最后一天才想起要记日记。于是小蓝赶紧编了一些日记交给老师。

没想到,日记很快就被老师发现了问题,原来小蓝记完 8 月 31 日的日记,竟又记了 8 月 32 日和 8 月 33 日的日记。这显然是有问题的,因为根本没有 8 月 32 日和 8 月 33 日。

给定一个月份和一个日期,请问 2021 年有没有这一天。

输入描述

输入的第一行包含一个整数 mm,表示月份。

第二行包含一个整数 dd,表示日期。

其中,1≤m≤20,1≤d≤40。

输出描述

如果2021年有 m月 d 日,输入 yes,否则输出 no

输入输出样例

示例 1

输入

8
32

输出

no

示例 2

输入

2
28

输出

yes

运行限制

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

#include <iostream>
using namespace std;
int D[13]={
  -1,31,28,31,30,31,30,31,31,30,31,30,31
};
bool checkLeapYear(int y){
  if(y%400==0||(y%4==0&&y%100!=0)) return true;
  return false;
}
int main()
{
  int y=2021;
  int m,d;
  cin >>m>>d;
  if(checkLeapYear(y)) D[2] = 29;
  else D[2] = 28;
  if (m<0||m>13||d<0||d>D[m]) {
    cout <<"no"<<endl;
    return 0;}
  cout <<"yes"<<endl;

  // 请在此输入您的代码
  return 0;
}

第五题 特别数的和

题目描述

小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。

请问,在 1 到 nn 中,所有这样的数的和是多少?

输入描述

输入格式:

输入一行包含两个整数 n(1<n < 10^4)。

输出描述

输出一行,包含一个整数,表示满足条件的数的和。

输入输出样例

示例

输入

40

输出

574

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
int d[4] = {2,0,1,9};
bool geshu(int m){
  for (int j=0;j<4;j++){
    if (m == d[j]) return true;
  }
  return false;
}
int main()
{
  int n;
  int cnt =0;
  cin >> n;
  int temp;
  for (int i = 1;i<=n;i++){//i = 29
    temp = i;
    while(temp){
      int g = temp%10;
      if(geshu(g)) {
        cnt += i;
        break;
        }
      temp/=10;

    }
  }
  cout <<cnt <<endl;
  // 请在此输入您的代码
  return 0;
}

其中 for循环中的i不能发生改变。否则可能无限循环

第六题 猴子分香蕉

题目描述

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

5 只猴子是好朋友,在海边的椰子树上睡着了。这期间,有商船把一大堆香蕉忘记在沙滩上离去。

第 1 只猴子醒来,把香蕉均分成 5 堆,还剩下 1 个,就吃掉并把自己的一份藏起来继续睡觉。

第 2 只猴子醒来,把香蕉均分成 55堆,还剩下 2 个,就吃掉并把自己的一份藏起来继续睡觉。

第 3 只猴子醒来,把香蕉均分成 5 堆,还剩下 3 个,就吃掉并把自己的一份藏起来继续睡觉。

第 4 只猴子醒来,把香蕉均分成 5 堆,还剩下 4 个,就吃掉并把自己的一份藏起来继续睡觉。

第 5 猴子醒来,重新把香蕉均分成 5 堆,哈哈,正好不剩!

请计算一开始最少有多少个香蕉。

运行限制

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

#include <iostream>
using namespace std;
int main()
{
  int i =1;

  int res = 0;
  while(1){
    res = i;
    for (int j=1;j<=5;j++){
      
      if(res%5==0 &&j==5&&res>0) 
      {
        cout << i<<endl;
        return 0;
        }
      if (res%5==j&&res>0){
        res = res-j;
        res = res*4/5;
      }
      else break;
    }
    i++;
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/lishijie258/article/details/128632587