【全国青少年信息素养大赛智能算法挑战赛初中组复赛真题卷】

1. 修复机器人的对话词库错误

【题目描述】

基于人工智能技术的智能陪伴机器人的语言词库被黑客的病毒感染了,感染方 式是在单词中的某个字母被增加了两次,例如“hello”变成了“heeello” 。空格 字符被替换为长度不固定的数字乱码,请修复它。

【输入格式】

输入一行字符串 (字符串中无空格) 。这一行是被感染的字符串。

【输出格式】

输出一行对应的正确字符串。

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

Good24565morrrning

【样例输出】

Good morning

#include <bits/stdc++.h>
using namespace std;

string s;
//清理重复字
void clean(string s) {
	string t;
	int k;
	for(int i=0; i<s.size(); i++) {
		if(isalpha(s[i])&& s[i]==s[i+1] && s[i]==s[i+2]) {
			i += 1;
			continue;
		}
		t += s[i];
	}
	cout << t << endl;
}
int main() {
	string m;
	getline(cin, s);
//清理数字,并替换为一个空格
	for(int i=0; i<s.size(); i++) {
		if(isdigit(s[i])) {
			if(isdigit(s[i])&& isalpha(s[i+1])) {
				m +=" ";
			}
			continue;
		}
		m += s[i];
	}
	clean(m);//清理重复字符
	return 0;
}

2. 定制架子问题

【题目描述】

李莳花要做一个架子,把她喜欢的摆件叠放起来,她的每个摆件的位置顺序是固 定的。这个架子的宽度是 W,每层排放的摆件不能超过这个宽度,每层架子的高度不 能低于最高的摆件的高度。假设,给出排列好的每个摆件的宽度 Wi ,和高度 Hi ,请 计算需要最少多高的架子。

【输入格式】

输入的第一行有 2 个数字,一个是摆件的个数n,和架子的宽度 W。 以下摆件个数 n 行,每行的第一个数是摆件的宽度 Wi 和高度 Hi。

【输出格式】

输出放置摆件架子的最低高度。

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

5 5

2 1

1 2

1 3

2 3

2 2

【样例输出】

5

#include <bits/stdc++.h>
using namespace std;

/**
 * @brief 计算放置摆件所需架子的最低高度的函数
 * 
 * @param a 二维数组,存储每个摆件的宽度和高度
 * @param shelfwidth 架子的宽度限制
 * @param length 摆件的数量
 * @return 放置所有摆件所需架子的最低高度
 */
int minHeightShelves(int a[][2], int shelfwidth, int length) {
    // 初始化动态规划数组dp,dp[i]用于存储前i个摆件放置所需的最低架子高度
    int dp[length + 1] = {0};
    // 从第1个摆件开始计算
    for (int i = 1; i <= length; i++) { 
        // 用于累计当前考虑的摆件组合的总宽度
        int width = 0; 
        // 用于记录当前考虑的摆件组合中的最大高度
        int height = 0; 
        // 将当前状态初始化为极大值
        dp[i] = 0x3f3f3f3f; 
        // 从当前摆件往前回溯,寻找可以在同一层放置的摆件组合
        for (int j = i - 1; j >= 0; j--) { 
            // 如果加入当前摆件后总宽度超过架子宽度限制,停止该轮循环
            if (shelfwidth < (width += a[j][0])) { 
                break;
            }
            // 更新当前组合中的最大高度
            height = max(height, a[j][1]); 
            // 更新dp[i],取当前方案和之前计算的方案中的最小值
            dp[i] = min(dp[i], dp[j] + height); 
        }
    }
    // 返回放置所有摆件所需的最低架子高度
    return dp[length]; 
}


int main() {
    int a[10010][2]; // 存储摆件的宽度和高度的二维数组
    int n, shelfwidth, w, h; // 摆件数量、架子宽度、摆件宽度和高度

    // 输入摆件数量和架子宽度
    cin >> n >> shelfwidth; 
    // 循环输入每个摆件的宽度和高度
    for (int i = 0; i < n; i++) { 
        for (int j = 0; j < 2; j++) {
            cin >> a[i][j];
        }
    }
    // 调用计算最低架子高度的函数,并输出结果
    cout << minHeightShelves(a, shelfwidth, n)<< endl; 

    return 0;
}

3. 滑雪板打包问题

【题目描述】一家新开业的滑雪场,需要采购不同规格的滑雪板,每个滑雪板的长度是不固定的,现在需要把排列好的滑雪板用木板做成木箱封装好进行快递,每次快递的总重量是有限制的,不能超过重量G。只要每次打包的重量不超过G,多个滑雪板可以放在一起,使用与最长滑雪板长度相同的两个木板进行固定。假设,给出排列好的每个滑雪板的重量G,和长度L,请计算需要最少多长的木板才能将所有的滑雪板把包好。

【输入格式】输入的第一行有两个数字,一个是滑雪板的个数,一个是包裹总重量。以下滑雪板个数行,每行的第一个数是滑雪板的重量G,和长度L。

【输出格式】输出需要最少的木板的总长度。注:每次打包需要2个木板。

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

5 5

2 1

1 2

1 3

2 3

2 2

【样例输出】

10

解析:采取如下的贪心策略:
首先按照滑雪板的长度降序排列,确保我们先处理最长的滑雪板。
然后,每次尽可能地放入最多重量不超过G的滑雪板,这意味着我们会尽量填满每个木箱的容量G。
每次装箱我们使用两块与最长滑雪板等长的木板,然后继续尝试填满下一个木板。

#include <bits/stdc++.h>
using namespace std;
//贪心
// 定义最大数量的滑雪板
const int MAX_N = 1000;
// 静态数组存储每块滑雪板的重量和长度
int weights[MAX_N];
int lengths[MAX_N];
int main( ) {
	int n,G; // 滑雪板的数量 n 和单次包裹的最大重量 G
	cin >> n >> G;
	for (int i = 0; i< n; ++i) {
		cin >> weights[i] >> lengths[i];
	}
// 按照长度进行冒泡降序排序
	for (int i=0; i<n; i++) {
		for (int j=0; j<n-i-1; j++) {
			if (lengths[i] < lengths[j+1]) {
				swap(lengths[j], lengths[j+ 1]);
				swap(weights[j], weights[j+ 1]);
			}
		}
	}
	int totalLength=0; // 记录所需要的总木板长度
	int currentPackageWeight=0; // 当前包裹的总重量
	int currentMaxLength=0;// 当前包裹中最长滑雪板的长度
	for (int i = 0; i< n; i++) { //如果当前包裹加上此滑雪板超过了重量 G,那么需要另外开始一个新包裹
		if (currentPackageWeight + weights[i] > G) {
			totalLength += currentMaxLength*2; // 更新总木板长度
			currentPackageWeight=0;// 重置当前包裹重量
			currentMaxLength=0;//重置当前最长滑雪板长度
		}
// 累加当前包裹的重量,并更新最长滑雪板长度
		currentPackageWeight += weights[i];
		currentMaxLength = max(currentMaxLength, lengths[i]);
	}
// 最后一个包裹(如果存在)也需要用木板包装
	if (currentPackageWeight >0) {
		totalLength += currentMaxLength * 2;
	}
	cout << totalLength <<endl; // 输出所需的总木板长度
	return 0;
}
#include <bits/stdc++.h>
using namespace std;

// 结构体
struct SkiBoard {
    int weight;
    int length;
};

bool compare(SkiBoard a, SkiBoard b) {
    return a.length > b.length;
}

int main() {
    int n, G; // 滑雪板的数量和单次包裹的最大重量G
    cin >> n >> G;
    SkiBoard *boards = new SkiBoard[n];
    for (int i = 0; i < n; ++i) {
        cin >> boards[i].weight >> boards[i].length;
    }

    // 根据滑雪板的长度进行降序排序
    std::sort(boards, boards + n, compare);

    int totalLength = 0; // 总共需要的木板长度
    int currentWeight = 0; // 当前包裹的总重量
    int currentLength = 0; // 当前木板需要的长度

    for (int i = 0; i < n; ++i) { 
        // 如果加上当前滑雪板的重量超过 G,则需要新的木板
        if (currentWeight + boards[i].weight > G) {
            // 累加当前木板的长度
            totalLength += currentLength * 2;
            // 重置当前木板的总重量和长度
            currentWeight = 0;
            currentLength = 0;

            // 累加当前滑雪板的重量到当前木板,并更新需要的木板长度
            currentWeight += boards[i].weight;
            currentLength = max(currentLength, boards[i].length);
        } else {
            // 累加当前滑雪板的重量到当前木板,并更新需要的木板长度
            currentWeight += boards[i].weight;
            currentLength = std::max(currentLength, boards[i].length);
        }
    }
    // 不要忘记最后一块木板的长度
    if (currentWeight > 0) {
        totalLength += currentLength * 2;
    }
    cout << totalLength << endl;

    delete[] boards;

    return 0;
}
#include <bits/stdc++.h>
using namespace std;

int minHeightshelves(int a[][2], int shelfwidth, int length) {
	int dp[length+1]= {0}; //存状态
	for(int i=1; i<= length; i++) {
		int width = 0;
		int height = 0;
		dp[i] = 0x3f3f3f3f;
		for(int j=i-1; j>=0; j--) {
			if(shelfwidth<(width+=a[j][0])) {

				break;
			}
			height = max(height, a[j][1]);
			dp[i] = min(dp[i], dp[j]+height);
		}
		cout << dp[i] << endl;
	}
	return 2*dp[length];
}
int main() {
	int a[10010][2];
	int n;
	int shelfwidth;
	int w, h;
	cin >> n >> shelfwidth;
	for(int i=0; i<n; i++) {
		for(int j=0; j<2; j++) {
			cin >> a[i][j];
		}
	}
	cout <<  minHeightshelves(a, shelfwidth, n)<< endl;
	return 0;
}

4、 在 AI 下棋程序中,计算猫抓老鼠游戏的概率

【题目描述】

有这样一个游戏:在一个 n*n 的格子棋盘里,n 是奇数;有两种棋子,一个是只 能横向移动的棋子猫,一个是可以上下左右移动的棋子老鼠。假设老鼠在棋盘的正 中央,第一步老鼠将进行上下左右的随机移动。棋子猫在从棋盘的中间行的最左边 向棋盘的最右边移动,棋子猫每次移动只能是从左到右移动一步,第一步是猫位于 棋盘的中间行的最左边格子。请问:在猫移动到棋盘外面前,会有多大概率抓到老 鼠?

【输入格式】

输入一个大于 1 的奇数n,表示棋盘的大小。

【输出格式】

棋子猫抓到棋子老鼠的概率。(小数四舍五入保留4 位有效数字) 【样例输入】(测试数据不包含本样例)

3

【样例输出】0.6667

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汉子萌萌哒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值