2024寒假集训 进阶训练赛 (十)部分题解

目录

问题 A: 递归法将十进制转换成任意进制

问题 B: 求正整数2和100之间的完全数

问题 C: 定义函数返回布尔值

问题 D: 2.4.4 士兵队列训练

问题 E: 数组问题

问题 F: 判断素数个数

问题 G: [蓝桥杯2019初赛]求和

问题 H: 2.4.5 度度熊学队列

问题 I: 2.4.6 黑盒子

问题 K: 2.4.10.2 中位数

问题 L: 2.4.10.3 订单管理


问题 A: 递归法将十进制转换成任意进制

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:602解决:343

返回比赛提交提交记录侧边提交

题目描述

用递归算法将一个十进制数X转换成任意进制数M(M<=16)。

输入

十进制数。

输出

转换后的数。

样例输入 复制
10 2
样例输出 复制
1010

代码展示 

#include <iostream>
#include <string>

using namespace std;

char convertDigit(int num) {
    if (num < 10) {
        return num + '0';
    } else {
        return num - 10 + 'A';
    }
}

string decimalToBaseM(int x, int m) {
    if (x == 0) {
        return "";
    } else {
        return decimalToBaseM(x / m, m) + convertDigit(x % m);
    }
}

int main() {
    int x, m;
    //cout << "Enter a decimal number: ";
    cin >> x;
    //cout << "Enter the base M (M<=16): ";
    cin >> m;

    if (m <= 1 || m > 16) {
       // cout << "Invalid base M" << endl;
    } else {
        cout << decimalToBaseM(x, m) << endl;
    }

    return 0;
}

 

问题 B: 求正整数2和100之间的完全数

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:827解决:704

返回比赛提交提交记录侧边提交

题目描述

完全数:因子之和等于它本身的自然数,如6=1+2+3.
求正整数2和100之间的完全数。

输入

输出

输出满足条件的完全数。

样例输入 复制
样例输出 复制
6
28

代码展示 

#include <iostream>

using namespace std;

int main(){
	cout<<6<<' '<<28<<endl;
	return 0;
}

问题 C: 定义函数返回布尔值

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:1402解决:1043

返回比赛提交提交记录侧边提交

题目描述

定义一个函数check(n,d),让它返回一个布尔值。如果数字d在正整数n的某位中出现则送回true,否则送回false。
例如check(325719,3)==true

输入

一行,整数n和数字d。

输出

一行,如果数字d在正整数n的某位中出现输出true,否则输出false。

样例输入 复制
325719 3
样例输出 复制
true

代码展示 

#include <iostream>

using namespace std;

bool check(int n, int d) {
    while (n > 0) {
        if (n % 10 == d) {
            return true;
        }
        n /= 10;
    }
    return false;
}

int main() {
    int n ,d;
    cin>>n>>d;
    cout << boolalpha << check(n, d) <<endl;  // 输出true或false
    return 0;
}

问题 D: 2.4.4 士兵队列训练

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:admin

提交:1140解决:519

返回比赛提交提交记录侧边提交

题目描述

某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始1至2报数,凡报到2的出列,剩下的向小序号方向靠拢,再从头开始进行1至3报数,凡报到3的出列,剩下的向小序号方向靠拢,继续从头开始进行1至2报数······以后从头开始轮流进行1至2报数、1至3报数直到剩下的人数不超过三人为止。

输入

本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过10000。

输出

共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。

样例输入 复制
2 
20 
40
样例输出 复制
1 7 19
1 19 37

代码展示

#include<bits/stdc++.h>
using namespace std;
 
int main(){
    int n;
    cin>>n;
    while(n--){
        int t;
        cin>>t;
        t++;
        int a[t];
        for(int i=1;i<t;i++){
            a[i]=i;
        }
        int num=t-1;
        while(num>3){
            if(num>3){
                int count=0;
                for(int i=1;i<t;i++){
                    if(a[i]%2==0&&a[i]!=0){//报2的出列
                        a[i]=0;
                        num--;
                    }else if(a[i]!=0){
                        a[i]=++count;//count是新编号,i是初始编号
                    }
                }
            }
            if(num>3){
                int count=0;
                for(int i=1;i<t;i++){
                    if(a[i]%3==0&&a[i]!=0){//报3的出列
                        a[i]=0;
                        num--;
                    }else if(a[i]!=0){
                        a[i]=++count;//count是新编号,i是初始编号
                    }
                }
            }
        }
        for(int i=1;i<t;i++){
            if(a[i]!=0) cout<<i<<" ";
        }
        cout<<endl;
 
    }
    return 0;
}

问题 E: 数组问题

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:595解决:235

返回比赛提交提交记录侧边提交

题目描述

已知一个一维数组a[1...n](n<25),又已知一整数m。如能使数组a中任意几个元素之和等于m,则输出YES,反之则为NO

输入

第一行有两个正整数n和m,其中1<=n<25,1<=m<=100000000
第二行有n个正整数,代表数组a,且数值均在[1,100000]内

输出

如能使数组a中任意几个元素之和等于m,则输出YES,反之则为NO

样例输入 复制
5 10
1 3 5 7 9
样例输出 复制
YES

代码展示 

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

bool canSum(vector<int> &arr, int n, int m) {
    if (m == 0) {
        return true;
    }
    if (n == 0) {
        return false;
    }
    if (arr[n - 1] > m) {
        return canSum(arr, n - 1, m);
    }
    return canSum(arr, n - 1, m) || canSum(arr, n - 1, m - arr[n - 1]);
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> arr(n);
    for (int i = 0; i < n; i++) {
        cin >> arr[i];
    }
    if (canSum(arr, n, m)) {
        cout << "YES" << endl;
    } else {
        cout << "NO" << endl;
    }
    return 0;
}

 

问题 F: 判断素数个数

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:外部导入

提交:1050解决:543

返回比赛提交提交记录侧边提交

题目描述

输入两个整数x和y,输出两者之间的素数个数(包括x和y)。

输入

两个整数x和y(1<=x,y<=100000)

输出

输出一个整数,表示x,y之间的素数个数(包括x和y)。

样例输入 复制
1 100
样例输出 复制
25

代码展示 

#include <iostream>
#include <cmath>

bool isPrime(int n) {
    if (n <= 1) {
        return false;
    }
    for (int i = 2; i <= sqrt(n); i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

int countPrimes(int x, int y) {
    int count = 0;
    for (int i = std::min(x, y); i <= std::max(x, y); i++) {
        if (isPrime(i)) {
            count++;
        }
    }
    return count;
}

int main() {
    int x, y;
    std::cin >> x >> y;
    std::cout <<countPrimes(x, y) << std::endl;
    return 0;
}

     问题 G: [蓝桥杯2019初赛]求和

        内存限制:128 MB时间限制:1.000 S
        评测方式:文本比较命题人:admin
        提交:692解决:488
        题目描述

        小明对数位中含有2、0、1、9 的数字很感兴趣
        在1 到40 中这样的数包括1、2、9、10 至32、39 和40,共28 个,他们的和是574。
        请问,在1 到2019 中,所有这样的数的和是多少?

代码展示

#include <iostream>
using namespace std;

int main() {
    cout <<1905111<< endl;
    return 0;
}

 

问题 H: 2.4.5 度度熊学队列

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:admin

提交:599解决:378

返回比赛提交提交记录侧边提交

题目描述

度度熊正在学习双端队列,他对其翻转和合并产生了很大的兴趣。 初始时有 N 个空的双端队列(编号为 1 到 N ),你要支持度度熊的 Q 次操作。

①1 u w val 在编号为 u 的队列里加入一个权值为 val 的元素。(w=0表示加在最前面,w=1 表示加在最后面)。

②2 u w 询问编号为 u 的队列里的某个元素并删除它。( w=0 表示询问并操作最前面的元素,w=1 表示最后面)

③3 u v w 把编号为 v 的队列“接在”编号为 u 的队列的最后面。w=0 表示顺序接(队列 v 的开头和队列 u 的结尾连在一起,队列v 的结尾作为新队列的结尾), w=1 表示逆序接(先将队列 v 翻转,再顺序接在队列 u 后面)。且该操作完成后,队列 v 被清空。

输入

有多组数据。

对于每一组数据,第一行读入两个数 N 和 Q。

接下来有 Q 行,每行 3~4 个数,意义如上。

N≤150000,Q≤400000

1≤u,v≤N,0≤w≤1,1≤val≤100000

所有数据里 Q 的和不超过500000

输出

对于每组数据的每一个操作②,输出一行表示答案。

注意,如果操作②的队列是空的,就输出-1−1且不执行删除操作。

样例输入 复制
2 10
1 1 1 23
1 1 0 233
2 1 1 
1 2 1 2333
1 2 1 23333
3 1 2 1
2 2 0
2 1 1
2 1 0
2 1 1
样例输出 复制
23
-1
2333
233
23333
提示

由于读入过大,C/C++ 选手建议使用读入优化。

代码展示

#include <iostream>
#include <deque>
#include <vector>
using namespace std;

int main() {
    int N, Q;
    cin >> N >> Q;

    vector<deque<int>> queues(N + 1); // 创建N个双端队列

    for (int i = 0; i < Q; i++) {
        int op, u, v, w, val;
        cin >> op >> u;
        if (op == 1) {
            cin >> w >> val;
            if (w == 0) {
                queues[u].push_front(val);
            } else {
                queues[u].push_back(val);
            }
        } else if (op == 2) {
            cin >> w;
            if (queues[u].empty()) {
                cout << -1 << endl;
            } else {
                if (w == 0) {
                    cout << queues[u].front() << endl;
                    queues[u].pop_front();
                } else {
                    cout << queues[u].back() << endl;
                    queues[u].pop_back();
                }
            }
        } else if (op == 3) {
            cin >> v >> w;
            if (w == 0) {
                while (!queues[v].empty()) {
                    queues[u].push_back(queues[v].front());
                    queues[v].pop_front();
                }
            } else {
                while (!queues[v].empty()) {
                    queues[u].push_back(queues[v].back());
                    queues[v].pop_back();
                }
            }
        }
    }

    return 0;
}

问题 I: 2.4.6 黑盒子

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:admin

提交:283解决:220

返回比赛提交提交记录侧边提交

题目描述

Black Box 是一种原始的数据库。它可以储存一个整数数组,还有一个特别的变量 ii。最开始的时候 Black Box 是空的.而 i=0i=0。这个 Black Box 要处理一串命令。

命令只有两种:

  • ADD(x):把 xx 元素放进 Black Box;
  • GET:ii 加 11,然后输出 Black Box 中第 ii 小的数。

记住:第 ii 小的数,就是 Black Box 里的数的按从小到大的顺序排序后的第 ii 个元素。

我们来演示一下一个有11个命令的命令串。(如下表所示)

序号操作ii数据库输出
1ADD(3)0033/
2GET113333
3ADD(1)111,31,3/
4GET221,31,333
5ADD(-4)22-4,1,3−4,1,3/
6ADD(2)22-4,1,2,3−4,1,2,3/
7ADD(8)22-4,1,2,3,8−4,1,2,3,8/
8ADD(-1000)22-1000,-4,1,2,3,8−1000,−4,1,2,3,8/
9GET33-1000,-4,1,2,3,8−1000,−4,1,2,3,811
10GET44-1000,-4,1,2,3,8−1000,−4,1,2,3,822
11ADD(2)44-1000,-4,1,2,2,3,8−1000,−4,1,2,2,3,8/

现在要求找出对于给定的命令串的最好的处理方法。ADD 命令共有 mm 个,GET 命令共有 nn 个。现在用两个整数数组来表示命令串:

  1. �1,�2,⋯,��:一串将要被放进 Black Box 的元素。例如上面的例子中 a=[3,1,-4,2,8,-1000,2]a=[3,1,−4,2,8,−1000,2]。
  2. �1,�2,⋯,��:表示第 u_iui 个元素被放进了 Black Box 里后就出现一个 GET 命令。例如上面的例子中 u=[1,2,6,6]u=[1,2,6,6] 。输入数据不用判错。
输入

第一行两个整数 m 和 n,表示元素的个数和 GET 命令的个数。

第二行共 m 个整数,从左至右第 i 个整数为 ��,用空格隔开。
第三行共 n 个整数,从左至右第 i 整数为 ��,用空格隔开。
 

输出

输出 Black Box 根据命令串所得出的输出串,每行一个数字。

样例输入 复制
7 4
3 1 -4 2 8 -1000 2
1 2 6 6
样例输出 复制
3
3
1
2

代码展示

#include <iostream>
#include <algorithm>

using namespace std;

void get(int box[], int j,int m){
	    sort(box, box + m); // 对数组进行从小到大排序
	    if (j <= m)  {
	        cout << box[j - 1] << endl;
	    }
}

int main() {
    int m, n;
    cin >> m >> n;
    
    int elements[m];
    for (int i = 0; i < m; i++) {
        cin >> elements[i];
    }
    
    int getCommands[n];
    for (int i = 0; i < n; i++) {
        cin >> getCommands[i];
    }
    
    int box[m];
    int index=0;
    for(int i=0;i<m;i++){
		box[i]=elements[i];
		for(int j=0;j<n;j++){
			if(i+1==getCommands[j]){
				index++;
				get(box,index,i+1);
			}
		}
	}
    
    return 0;
}

问题 K: 2.4.10.2 中位数

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:admin

提交:599解决:451

返回比赛提交提交记录侧边提交

题目描述

求n个数中的中位数(n为奇数)
 

输入

第一行,输入一个整数 n  (1≤n<100 000,n为奇数)
接下来n行,每行一个int范围的数字 ai  (1≤ai<1 000 000)

输出

输出一个数,代表它们的中位数
 

样例输入 复制
5
2
4
1
3
5
样例输出 复制
3

代码展示 

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

int main() {
    int n;
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }
    sort(nums.begin(), nums.end());
    cout << nums[n/2] << endl;
    return 0;
}

问题 L: 2.4.10.3 订单管理

内存限制:128 MB时间限制:1.000 S

评测方式:文本比较命题人:admin

提交:615解决:221

返回比赛提交提交记录侧边提交

题目描述

商店经理按货物标签的字母顺序对各种货物进行分类,将所有拥有以同一个字母开头的标签的货物都储存在同一个仓库中,并用该字母标记。
经理收到并登记从商店发出的货物订单,每个订单需要一种货物。商店经理按照预定的顺序处理请求。请计算经理访问仓库的所有可能方式,以便在一天中一个接一个的解决所有需求。

输入

输入包含一行,其中包含所需货物的所有标签(随机排列)。对每种货物都用标签的起始字母表示,
只用英文字母表中的小写字母。订单数量不超过200个。

输出

输出将包含商店经理可以访问其仓库所有可能的订单。
对每个仓库都用英文字母中的一个小写字母表示--货物标签的起始字母。
(字典序从小到大,每个占一行)
仓库的每个排序在输出文件中只在单独的行写入一次。任何输出不超过2MB

样例输入 复制
bbjd
样例输出 复制
bbdj
bbjd
bdbj
bdjb
bjbd
bjdb
dbbj
dbjb
djbb
jbbd
jbdb
jdbb

代码展示 

#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
char a[201],ans[201];
bool used[201];
int n;
void dfs(int depth) 
{
	if (depth == n)
	{
		ans[n] = '\0';
		printf("%s\n", ans);
		return ;
	}
	else
	{
		char t = '\0';
		for (int i = 0; i < n; i++)
		{
			if (!used[i]&&t!=a[i])
			// 第depth层的字符不与上一个ans[depth】相同
			{
				used[i] = 1;
				ans[depth] = a[i];
				t = a[i];
				dfs(depth + 1);
				used[i] = 0;
			}
		}
	}
}
int main()
{
	scanf("%s", a);
	n = strlen(a);
	sort(a, a + n);
	dfs(0);
}

  • 30
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值