202312-1 小猫分鱼

题目描述

海滩上有一堆鱼,​N 只小猫来分。第一只小猫把这堆鱼平均分为 ​N 份,多了 ​i<N 个,这只小猫把多的 ​i 个扔入海中,拿走了一份。第二只小猫接着把剩下的鱼平均分成 ​N 份,又多了 ​i 个,小猫同样把多的 ​i 个扔入海中,拿走了一份。第三、第四、……,第 ​N 只小猫仍是最终剩下的鱼分成 ​N 份,扔掉多了的 ​i 个,并拿走一份。

编写程序,输入小猫的数量 ​N 以及每次扔到海里的鱼的数量 ​i,输出海滩上最少的鱼数,使得每只小猫都可吃到鱼。

例如:两只小猫来分鱼 ​N=2,每次扔掉鱼的数量为 ​i=1,为了每只小猫都可吃到鱼,可令第二只小猫需要拿走 ​1 条鱼,则此时待分配的有 ​3 条鱼。第一只小猫待分配的鱼有 ​3\times 2+1=7 条。

输入格式

总共 ​2 行。第一行一个整数 ​N,第二行一个整数 ​i

保证 ​0<N<10​i<N

输出格式

一行一个整数,表示满足要求的海滩上最少的鱼数。

样例输入 1

2
1

样例输出 1

7

样例输入 2

3
1

样例输出 2

25

提示

【样例解释 2】

三只小猫来分鱼 ​N=3,每次扔掉鱼的数量为 ​i=1,为了每只小猫都可吃到鱼,可令第三只小猫需要拿走 ​3 条鱼(拿走 ​1 条和 ​2 条不满足要求),则此时待分配的有 ​10 条鱼。第二只小猫待分配的鱼有 ​10×3/2+1 = 16 条。第一只小猫待分配的鱼有 ​16×3/2+1 = 25 条。

代码解析

根据题意倒着往前推即可

#include<bits/stdc++.h>
using namespace std;
bool fish(int i, int j, int n) {
    int sum = j;
    for (int k = 0; k < n; k++) {
        if (k != 0) {
            if (sum % (n-1) != 0) {
                return false;
            }
            sum /= (n-1);
        }
        sum *= n;
        sum += i;   
    }
    cout << sum;
    return true;
}
int main() {

    int n, i, sum;
    cin >> n >> i;
    for (int j = 1; ; j++) {
		if (fish(i, j, n))
            break;
    }
  
    return 0;
}

202312-2 单位转换

题目描述

小杨这周的数学作业是做单位转换,喜欢编程的小杨决定编程帮他解决这些问题。

小杨只学了长度单位和重量单位,具体来说:

  • 长度单位包括千米(km)、米(m)、毫米(mm),它们之间的关系是:​1\text{km} = 1000\text{m} = 1000000\text{mm}
  • 重量单位包括千克(kg)、克(g)、毫克(mg),它们之间的关系是:​1\text{kg} = 1000\text{g} = 1000000\text{mg}

小杨的作业只涉及将更大的单位转换为更小的单位,也就是说,小杨的作业只会包含如下题型:米转换为毫米,千米转换为毫米,千米转换为米,克转换为毫克,千克转换为毫克,千克转换为克。

现在,请你帮忙完成单位转换的程序。

输入格式

输入的第一行为一个整数,表示题目数量。

接下来 ​N 行,每行一个字符串,表示转换单位的题目,格式为 ​x 单位 ​1 = ? 单位 ​2。其中,​x 为一个不超过 ​1000 的非负整数, 单位 ​1 和 单位 ​2 分别为两个单位的英文缩写,保证它们都是长度单位或都是重量单位,且 单位 1单位 2 更大。

例如,如果题目需要你将 ​1\text{km} 转换为 ​\text{mm},则输入为 1 km = ? mm

保证 ​1\le N \le 1000

输出格式

输出 ​N 行,依次输出所有题目的答案,输出时,只需要将输入中的 ​? 代入答案,其余部分一字不差地输出即可。由于小杨的题目只涉及将更大的单位转换为更小的单位,并且输入的 ​x 是整数,因此答案一定也是整数。

例如,如果题目需要你将 ​1\text{km} 转换为 ​\text{mm},则输入为 1 km = ? mm。则你需要输出 1 km = 1000000 mm

样例输入 1

2
1 km = ? mm
1 m = ? mm

样例输出 1

1 km = 1000000 mm
1 m = 1000 mm

样例输入 2

5
100 m = ? mm
1000 km = ? m
20 kg = ? g
200 g = ? mg
0 kg = ? mg

样例输出 2

100 m = 100000 mm
1000 km = 1000000 m
20 kg = 20000 g
200 g = 200000 mg
0 kg = 0 mg

代码解析

直接使用 cin 输入,避免之后还需要字符串分割,输入的时候可以将 ?和 = 都忽略掉

因为题目中说了只能是“大转小”,所以当第一个单位是 m 或者 g 的时候,只能是转到 mm 或者 mg,当第二个单位是 m 或者 g 的时候只能是 km 转 m 或者 kg 转 g,所以这两种可能性都是直接乘 1000,除此之外肯定是 kg 转 mg,或者 km 转 mm

void get(int n, string s1, string s2) {
    int m;
    if (s1 == "m" || s1 == "g")
        m = 1000 * n;
    else if (s2 == "m" || s2 == "g")
        m = 1000 * n;
    else
        m = 1000000 * n;
    cout << n << ' '+s1+" = " << m << ' '+s2 << endl;
}

观察函数发现代码有些繁琐,而且不管是 m 还是 g,他都是长度为 1 的字符串,所以优化后:

#include<bits/stdc++.h>
using namespace std;
void get(int n, string s1, string s2) {
    int m;
    if (s1.size() == 1 || s2.size() == 1)
        m = 1000 * n;
    else
        m = 1000000 * n;
    cout << n << ' '+s1+" = " << m << ' '+s2 << endl;
}
int main() {
    int n;
    cin >> n;
    while (n--) {
        int a;
        string s1, s2;
        cin >> a >> s1 >> s2 >> s2 >> s2;
        get(a, s1, s2);
    }
    return 0;
}

202309-1 小杨的储蓄

题目描述

小杨共有 ​N 个储蓄罐,编号从 ​0​N-1。从第 ​1 天开始,小杨每天都会往存钱罐里存钱。具体来说,第 ​i 天他会挑选一个存钱罐 ​a_i,并存入 ​i 元钱。过了 ​D 天后,他已经忘记每个储蓄罐里都存了多少钱了,你能帮帮他吗?

输入格式

输入 ​2 行,第一行两个整数 ​N,D;第二行 ​D 个整数,其中第 ​i 个整数为 ​{a_i}(保证 ​0 \le a_i \le N-1)。

每行的各个整数之间用单个空格分隔。

保证 ​1 \le N \le 1,000​1 \le D \le 1,000

输出格式

输出 ​N 个用单个空格隔开的整数,其中第 ​i 个整数表示编号为 ​i-1 的存钱罐中有多少钱(​i=1, \cdots ,N)。

样例输入 1

2 3
0 1 0

样例输出 1

4 2

样例输入 2

3 5
0 0 0 2 0

样例输出 2

11 0 4

提示

【样例解释 1】

小杨在第 ​1 天、第 ​2 天、第 ​3 天分别向 ​0 号、 ​1 号、 ​0 号存钱罐存了 ​1 元钱、 ​2 元钱、 ​3 元钱,因此 ​0 号存钱罐有 ​1+3=4 元钱,而 ​1 号存钱罐有 ​2 元钱。

代码解析

i 天会给 m 号存钱罐投入 i 元,所以我们只需要给 money[m] 加上 i 即可,最后输出的时候注意,下标是从 0 开始的

#include<iostream>
using namespace std;
int main() {
	int N, D, money[1001] = {0};
    cin >> N >> D;
    for (int i = 1; i <= D; i++) {
        int m;
        cin >> m;
        money[m] += i;
    }
    for (int i = 1; i <= N; i++) 
        cout << money[i-1] << ' ';
    return 0;
}

202309-2 进制判断

题目描述

​N 进制数指的是逢 ​N 进一的计数制。例如,人们日常生活中大多使用十进制计数,而计算机底层则一般使用二进制。除此之外,八进制和十六进制在一些场合也是常用的计数制(十六进制中,一般使用字母 A 至 F 表示十至十五)。

现在有N个数,请你分别判断他们是否可能是二进制、八进制、十进制、十六进制。例如,15A6F 就只可能是十六进制,而 1011 则是四种进制皆有可能。

输入格式

输入的第一行为一个十进制表示的整数 ​N。接下来 ​N 行,每行一个字符串,表示需要判断的数。保证所有字符串均由数字和大写字母组成,可能以 ​0 开头。保证不会出现空行。

保证 ​1 \le N \le 1000,保证所有字符串长度不超过 ​10

输出格式

输出 ​N 行,每行 ​4 个数,用空格隔开,分别表示给定的字符串是否可能表示一个二进制数、八进制数、十进制数、十六进制数。使用 ​1 表示可能,使用 ​0 表示不可能。

例如,对于只可能是十六进制数的 15A6F,就需要输出 0 0 0 1;而对于四者皆有可能的 1011,则需要输出 1 1 1 1

样例输入 1

2
15A6F
1011

样例输出 1

0 0 0 1
1 1 1 1

样例输入 2

4
1234567
12345678
FF
GG

样例输出 2

0 1 1 1
0 0 1 1
0 0 0 1
0 0 0 0

代码解析

可以用笨办法,定义 bool 变量 k2, k8, k10, k16,当遇到不同范围字符,做好标记就可以

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

void check(string s) {
    bool k2=1, k8=1, k10=1, k16=1;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] >= '2' && s[i] <= '9' || s[i] >= 'A')
            k2 = 0;
        if (s[i] >= '8' && s[i] <= '9' || s[i] >= 'A')
            k8 = 0;
        if (s[i] >= 'A')
            k10 = 0;
        if (s[i] >= 'G')
            k16 = 0;
    }
    cout << k2 << ' ' << k8 << ' ' << k10 << ' ' << k16 << endl;
}

int main() {
	int n;
    cin >> n;
   	while (n--) {
        string s;
        cin >> s;
        check(s);
    }
    return 0;
}

202306-1 春游

题目描述

老师带领同学们春游。已知班上有 ​N 位同学,每位同学有从 ​0​N-1 的唯一编号。到了集合时间,老师确认是否所有同学都到达了集合地点,就让同学们报出自己的编号。到达的同学都会报出自己的编号,不会报出别人的编号,但有的同学很顽皮,会多次报出。你能帮老师找出有哪些同学没有到达吗 ?。

输入格式

输入包含 ​2 行。第一行包含两个整数 ​N​M,表示班级有 ​N 位同学,同学们共有 ​M 次报出编号。约定 ​2 \le N,M \le 1000
第二行包含 ​M 个整数,分别为 ​M 次报出的编号。约定所有编号是小于 ​N 的非负整数。

输出格式

输出一行。如果所有同学都到达,则输出 ​N;否则由小到大输出所有未到达的同学编号,空格分隔。

样例输入 1

3 3
0 2 1

样例输出 1

3

样例输入 2

3 5
0 0 0 0 0

样例输出 2

1 2

代码解析

使用数组来标记已经报过数的同学编号,每次报数 n,我们就将 student[n] 标记为 1

需要一个 bool 变量 all 来标记是否全部到达

#include<iostream>
using namespace std;
bool student[1001];
int main() {
    int N, M, n;
    cin >> N >> M;
    for (int i = 0; i < M; i++) {
        cin >> n;
        student[n] = 1;
    }
    bool all = true;
    for (int i = 0; i < N; i++) {
        if (!student[i]) {
            cout << i << ' ';
            all = false;
        }
    }
    if (all) cout << N;
    return 0;
}

202306-2 密码合规

题目描述

网站注册需要有用户名和密码,编写程序以检查用户输入密码的有效性。合规的密码应满足以下要求 :。

  1. 只能由 ​\texttt a \sim \texttt z 之间 ​26 个小写字母、​\texttt A \sim \texttt Z 之间 ​26 个大写字母、​0 \sim 9 之间 ​10 个数字以及 !@#$ 四个特殊字符构成。
  2. 密码最短长度 ​:6 个字符,密码最大长度 ​:12 个字符。
  3. 大写字母,小写字母和数字必须至少有其中两种,以及至少有四个特殊字符中的一个。

输入格式

输入一行不含空格的字符串。约定长度不超过 ​100。该字符串被英文逗号分隔为多段,作为多组被检测密码。

输出格式

输出若干行,每行输出一组合规的密码。输出顺序以输入先后为序,即先输入则先输出。

样例输入 1

seHJ12!@,sjdkffH$123,sdf!@&12HDHa!,123&^YUhg@!

样例输出 1

seHJ12!@
sjdkffH$123

提示

【样例 1 解释】

输入被英文逗号分为了四组被检测密码:seHJ12!@sjdkffH$123sdf!@&12HDHa!123&^YUhg@!。其中 sdf!@&12HDHa! 长度超过 12 个字符,不合规;123&^YUhg@! 包含四个特殊字符之外的字符不合规。

代码解析

定义 check 函数来判断一个密码是否合规

check 函数中,定义 up, down, digit, chr 四个 bool 变量分别判断字符串中是否含有大写、小写、数字、特殊符号,遍历的过程中如果有就标记为 1,当全部遍历完成之后判断 up + low + digit >= 2 表示三个中至少有两个,再判断 chr 是否为真就可以

拼接分割密码的时候,注意最后一个密码不是以逗号 , 结尾的,所以最后需要再判断一下

#include<iostream>
#include<string>
using namespace std;
bool check(string s) {
    bool up = 0, low = 0, digit = 0, chr = 0;
    if (s.size() < 6 || s.size() > 12)
        return false;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] >= 'a' && s[i] <= 'z')
            low = 1;
        else if (s[i] >= 'A' && s[i] <= 'Z')
            up = 1;
        else if (s[i] >= '0' && s[i] <= '9')
            digit = 1;
        else if (s[i]=='!'||s[i]=='@'||s[i]=='#'||s[i]=='$')
            chr = 1;
        else
            return false;
    }
    if (up + low + digit >= 2 && chr)
        return true;
    else
        return false;
}
int main() {
	string s, password = "";
    cin >> s;
    for (int i = 0; i < s.size(); i++) {
        if (s[i] == ',') {
            if (check(password))
                cout << password << endl;
            password = "";
        } else {
            password += s[i];
        }
    }
    if (check(password))
        cout << password << endl;
    return 0;
}

Copyright © 2021-2025 可见