2024C++信息素养大赛-智能算法应用挑战赛_复赛真题(广东省)题目+参考答案和详细解析

CSDN 2024-07-30 11:05:03 阅读 90

1.翻转数相乘

【题目描述】

假设一个n位数,如a1a2a3...an,其中a1是这个数的第i位上的数字,,且这个n位数不是每个位都相等的数字,例如不是2222或类似。如果,有一个整数x,并且1<x<10,使得a1a2a3...an*x=an…a2a1,求x,其中a1和an不能为0,如果x无解,则输出0,如果有多个x,则从小到大输出,所有x的解,中间用空格隔开。例如:一个5位数,ABCDE*?=EDCBA其中A、B、C、D、E是个位整数,ABCDE和EDCBA是一个万位数,求符合这个等式的乘数。

【输入格式】输入1个数,表示要求解的n位数。

【输出格式】输出表示所有可能的乘数,并按照从小到大排列,用回车隔开。

【样例输入】(测试数据不包含本样例)

6

【样例输出】

4

9

<code>#include <bits/stdc++.h>

using namespace std;

// 将一个数字字符串反转

string reverseString(const string &str) {

string reversedStr = str; // 复制输入字符串

reverse(reversedStr.begin(), reversedStr.end()); // 反转字符串

return reversedStr; // 返回反转后的字符串

}

// 将一个数字字符串乘以一个整数

string multiplyStringByInt(const string &num, int x) {

string result; // 存储乘积结果

int carry = 0; // 进位

// 从最低位开始逐位相乘

for (int i = num.size() - 1; i >= 0; --i) {

int product = (num[i] - '0') * x + carry; // 当前位与 x 相乘,加上进位

result.push_back((product % 10) + '0'); // 保存当前位的结果

carry = product / 10; // 更新进位

}

// 处理剩余的进位

while (carry) {

result.push_back((carry % 10) + '0');

carry /= 10;

}

reverse(result.begin(), result.end()); // 反转结果字符串

return result; // 返回乘积结果

}

// 计算 10 的 n 次幂

int powerOfTen(int n) {

int result = 1; // 初始化结果为 1

for (int i = 0; i < n; ++i) {

result *= 10; // 连乘 n 次 10

}

return result; // 返回 10 的 n 次幂

}

// 检查某个 x 是否满足条件

bool isValid(int n, int x) {

int start = powerOfTen(n - 1); // n 位数的起始值(最低 n 位数)

int end = powerOfTen(n); // n 位数的终止值(超出 n 位数的最小值)

// 枚举所有 n 位数

for (int i = start; i < end; ++i) {

string original = to_string(i); // 将数字转换为字符串

string reversed = reverseString(original); // 反转字符串

string product = multiplyStringByInt(original, x); // 计算乘积

// 检查乘积是否等于反转后的字符串

if (product == reversed) {

return true; // 如果相等,返回 true

}

}

return false; // 如果没有满足条件的 x,返回 false

}

int main() {

int n; // 输入的 n 位数的位数

cin >> n; // 读取输入

vector<int> solutions; // 存储所有符合条件的 x

// 枚举所有可能的 x(从 2 到 9)

for (int x = 2; x < 10; ++x) {

if (isValid(n, x)) { // 检查 x 是否符合条件

solutions.push_back(x); // 如果符合,加入结果集

}

}

// 输出结果

if (solutions.empty()) { // 如果没有符合条件的 x

cout << 0 << endl; // 输出 0

} else {

for (size_t i = 0; i < solutions.size(); ++i) { // 遍历结果集

cout << solutions[i] << endl; // 输出每一个符合条件的 x

}

}

return 0; // 程序结束

}

2.吉利号码

[题目描述]

中国人喜欢图吉利,包括吉利数字,例如数字8或者数字6,尤其是连着的数字更加喜欢,比如手机号码,汽车车牌,房间号码等等。有需求就会有市场,吉利数字的号码,往往意味着更贵的价格。请你根据以下规则,编写一个程序,根据规则给一个号码设置相应的价格。

具体规则如下:

1.正常号码是100元。

2. 含有:6,8任何一个数字,每出现一次加50元,例如4326,6875,9918都符合加分标准。其中,6875被加2个50元,就相当于加100元。

3.如果出现升序或者降序的情况,不管升序还是降序,号码涨价3倍。例如:5678,4321都要贵3倍。注意:例如5567,4331等有相同元素的号码不算降序、升序。

4.如果出现三个相同数字情况,都涨6倍。例如:4888,6665,7777都满足加分的标准。注意:7777因为满足这条标准两次,所以这条规则给它涨两个6倍,也就是12倍。

5.如果符合AABB或者ABAB模式的,价格涨一倍。例如:2255,3939,7777都符合这个模式,所以都会涨价。注意:7777因为满足这条标准两次,所以这条标准给它涨2倍,同时7777也是连号,也会在之前连号的基础上继续涨价。

请编写程序按照所有规则,求一个号码的最终价格!要求程序从标准输入接收数据,在标准输出上输出结果。

[输入格式]

输入共1行,输入一个四位正整数,就是待计算的号码。

[输出格式]

输出共1行,一个整数,表示这个号码对应的销售价格。

[样例输入](测试数据不包含本样例)

6543

[样例输出]

450

#include<bits/stdc++.h>

using namespace std;

// 计算号码的销售价格

int calculatePrice(int number) {

string numStr = to_string(number); // 将数字转换为字符串方便处理

int price = 100; // 初始价格为100元

// 规则2:含有6或8的数字,每个加50元

for (char digit : numStr) {

if (digit == '6' || digit == '8') {

price += 50;

}

}

// 规则3:升序或降序,价格涨3倍

bool ascending = is_sorted(numStr.begin(), numStr.end());

bool descending = is_sorted(numStr.rbegin(), numStr.rend());

if (ascending || descending) {

price *= 3;

}

// 规则4:三个相同的数字,价格涨6倍

if (numStr[0] == numStr[1] && numStr[1] == numStr[2]) {

price *= 6;

} else if (numStr[1] == numStr[2] && numStr[2] == numStr[3]) {

price *= 6;

}

// 规则5:AABB或ABAB模式,价格涨1倍

if ((numStr[0] == numStr[1] && numStr[2] == numStr[3]) ||

(numStr[0] == numStr[2] && numStr[1] == numStr[3])) {

price *= 2;

}

return price;

}

int main() {

int number;

cin >> number; // 输入待计算的号码

int finalPrice = calculatePrice(number); // 计算号码的最终价格

cout << finalPrice << endl; // 输出最终价格

return 0;

}

3.将整数换成分数

[题目描述]

一个小于100万的正整数n,尝试把n变成带分数形式,也就是 n=a+b/c,其 中a,b,c是三个正整数,并且数字1~9(不含0)在a、b、c中,必须出现,且只能出现一次。例如:100=3+69258/714,其中1到9这9个数字全都出现了,并且只出现一次。当然,100还等于82+3546/197,也就是说将100变成带分数形式,会有两种组合方式。事实上100,可以写成11种1到9组成整数加上分数的形式。

请编写一个程序,根据一个输入N,程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部可能性。不要求输出每个表示,只输出有多少种表示法!

[输入格式]

输入一行,表示要分解的正整数。

[输出格式]

输出一行,表示有多少分法。

【样例输入](测试数据不包含本样例)

100

[样例输出]

11

#include<bits/stdc++.h>

using namespace std;

// 判断三个整数的组合是否包含1到9且每个数字只出现一次

bool isValidCombination(int a, int b, int c) {

string str = to_string(a) + to_string(b) + to_string(c);

if (str.size() != 9) return false; // 长度必须正好为9

unordered_set<char> digits(str.begin(), str.end());

return digits.size() == 9 && digits.find('0') == digits.end(); // 不包含0且包含所有数字1-9

}

int main() {

int n;

cin >> n;

int count = 0;

// 枚举所有可能的a,b,c

// 枚举所有可能的c

for (int c = 1; c <= 98765; ++c) {

// 枚举所有可能的a

for (int a = 1; a < n; ++a) {

// 计算 b 的值

int b = (n - a) * c;

// 检查是否符合数字组合条件

if (b > 0 && isValidCombination(a, b, c)) {

count++;

}

}

}

cout << count << endl;

return 0;

}

4.战胜白蚁

[题目描述]

小明因为很长时间没有回家,发现他家被白蚁给入侵了,白蚁特别喜欢啃食木头,因此他家的地板就遭殃了。小明要抢救被白蚁破坏的木地板,每个木地板由于白蚁的数量不同,每个地板进行维修的时间也不同,同时要争取及时修理越好,否则超过某个时间,这块地板就会被严重破坏掉。小明只能一块一块的清理白蚁,不能并行操作,也就是不能同时修多块地板。

请编写一个程序,根据每个地板的修理时间和如果不修理就会被白蚁完全损毁的 时间,进行一个最合理的排序,使得可以抢救最多的木板。输入是木板的数目,以及每个木板的维修时间和被破坏的时间,输出是能抢救的最多木板的数量。

[输入格式]

第一行是一个整数N(N小于50000),接下来N行每行两个整数T1,T2描述一个要修理的木板:修理这个木板需要T1秒,如果在T2秒之内还没有修理完成,这个木板就报废了。

[输出格式]

输出一个整数S,表示最多可以抢修S个木板。

[样例输入](测试数据不包含本样例)

4

100 200

200 1300

1000 1250

2000 3200

【样例输出]

3

#include <bits/stdc++.h>

using namespace std;

// 定义木板结构体

struct Board {

int T1; // 修理时间

int T2; // 被破坏时间

};

// 比较函数,按照 T2 升序排序

bool compare(Board& b1, Board& b2) {

return b1.T2 < b2.T2;

}

int rescueBoards(int N, vector<Board>& boards) {

// 按照 T2 升序排序

sort(boards.begin(), boards.end(), compare);

int rescuedCount = 0;

int currentTime = 0;

for (int i = 0; i < N; ++i) {

if (currentTime + boards[i].T1 <= boards[i].T2) {

rescuedCount++;

currentTime += boards[i].T1;

}

}

return rescuedCount;

}

int main() {

int N;

cin >> N;

vector<Board> boards(N);

for (int i = 0; i < N; ++i) {

cin >> boards[i].T1 >> boards[i].T2;

}

int result = rescueBoards(N, boards);

cout << result << endl;

return 0;

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。