【本套题的答题背景】
六一儿童节,学校组织同学们去湿地公园参加社会实践。
列队
时空限制 CPU占用时长: 1秒 内存使用限制: 128MB
题目描述
为了便于管理,所有参加活动的学生平均分成若干小组,每组学生人数相同。考虑到学生实际情况,小组个数至少 2 个且每个小组人数 不得少于 5 人。 已知学生总人数为 n ,统计有多少种分组方式。
输入格式
一个正整数 n,表示学生总人数
输出格式
一个整数,表示分组方式总数
输入输出样例
输入样例
20
输出样例
4
样例说明
只能平均分成 2 组或 4 组
数据范围与提示
输入的所有数据保证小于 1000
且保证学生可以被平均分为若干小组
答案
#include <bits/stdc++.h>
using namespace std;
int n, cnt;
int main() {
cin >> n;
for (int i = 2; i <= n / 5; i++) { // 枚举小组的数量,并保证每个组不少于 5 人
if (n % i == 0) cnt++;
}
cout << cnt;
return 0;
}
重组
时空限制 CPU占用时长: 1秒 内存使用限制: 128MB
题目描述
集合时,同学们发现老师们举着的不是熟悉的班牌,而是一些奇怪的数字。原来为了让同学们交到更多的朋友,在实践活动中所有师生重组编队。每位同学领取到一张写有一个 4 位数的卡片,同学们需要通过数位拆分将 4 个数字重组为两个数(可以有前导 0 ),两个数的最小和就是自己的队伍代号。在规定时间内找到自己所在队伍的同学可以得到额外加分。
输入格式
一个 4 位整数 n。
输出格式
一个整数,表示队伍代号。
输入输出样例
输入样例
2380
输出样例
31
样例说明
可重组为 08 和 23,和为 31
数据范围与提示
输入的所有数据保证符合规则
答案
// 方法 1:字符串存储
#include <bits/stdc++.h>
using namespace std;
char s[5];
int x, cnt, minn = 2e9;
int main() {
cin >> s;
sort(s, s + 4);
cout << (s[0] - '0' + s[1] - '0') * 10 + s[2] - '0' + s[3] - '0';
return 0;
}
// 方法 2:存进整数数组
#include <bits/stdc++.h>
using namespace std;
int a[5], x, cnt, minn = 2e9;
int main() {
cin >> x;
while (x) {
a[++cnt] = x % 10;
x /= 10;
}
sort(a + 1, a + 5); // 升序
cout << a[1] * 10 + a[2] * 10 + a[3] + a[4]; // 小的数作为十位数
return 0;
}
Chat
时空限制 CPU占用时长: 1秒 内存使用限制: 128MB
题目描述
A 组同学正兴高采烈地跟机器人聊天。同学向机器人提出自己关心的问题,机器人会给出一些“无厘头”的回答。机器人问答实质是根据同学的提问在系统知识库中寻找相似度系数最高的问题,并用该问题的答案进行回复。
相似度系数为两集合交集元素个数与并集元素个数之比(集合的交集和并集均会去除重复元素)。系数越高,两集合的相似度越高。
为了降低难度,以字母作为基本元素,请帮助机器人计算两个单词的相似度系数。
输入格式
两行,每行一个字符串,代表集合中的字母。输入字符串中没有多余空格。
输出格式
一个小数,保留 2 位小数,表示两个字母集合的相似度。
输入输出样例
输入样例
apple
bag
输出样例
0.17
样例说明
交集元素个数为 1 并集元素个数为 6
数据范围与提示
两个字符串均为小写字母,且长度均小于 255。
答案
#include <bits/stdc++.h>
using namespace std;
string a, b;
int jiao, bing;
int cnt1[130], cnt2[130];
int main() {
cin >> a >> b;
for (int i = 0; i < a.length(); i++) cnt1[a[i]]++; // 计数数组 1
for (int i = 0; i < b.length(); i++) cnt2[b[i]]++; // 计数数组 2
for (int i = 'a'; i <= 'z'; i++) {
bing += cnt1[i] || cnt2[i]; // 交集元素
jiao += cnt1[i] && cnt2[i]; // 并集元素
}
// cout << jiao << ' ' << bing << endl;
printf("%.2f", 1.0 * jiao / bing);
return 0;
}
闯关者
时空限制 CPU占用时长: 1秒 内存使用限制: 128MB
题目描述
B 组在玩拼图闯关。n 位同学按 1…n 编号顺时针方向围成一圈玩拼图。每一关同学们都会领到一个特殊的卡片,卡片拼接形成的玄妙图案就是开启下一关的钥匙。
这次的闯关规则如下:
第一轮由 11号同学拼图,把手中的卡片拼到图上(用掉手中的卡片),并喊出数字 1。对于之后的每一轮,假设上一轮喊出的数字是 x,则从上一轮喊出数字的下一位同学开始,沿着顺时针方向数 x 个同学。如果这个同学手中没有卡片,则继续顺时针方向数数,直到遇到第一个有卡片的同学为止。最后数到的有卡片同学会完成拼图(用掉手中的卡片),并且喊出这一轮中数过的总数 +1。所有同学按序完成拼图则闯关成功。具体流程如下:
假设有 7 位同学,拼图顺序为:①→②→④→⑦→⑤→⑥→③。
从①号同学开始沿顺时针方向数 1 个数轮到②号同学;
从②号沿顺时针方向数 2 个数轮到④号同学;
从④号数 3 个数轮到⑦号同学;
从⑦号数 4 个数轮到④号(无卡),继续数到 5 轮到⑤号同学;
从⑤号数 6 个数轮到④号(无卡),继续数到 8 轮到⑥号同学;
从⑥号数 9 个数轮到①号(无卡),继续数到 11 轮到③号同学,③号完成拼图闯关成功。
现有 n 位同学,请找出最后一位完成拼图的同学编号。
输入格式
一个正整数 n,表示小组人数。
输出格式
一个整数,表示最后一位完成拼图的同学编号。
输入输出样例
输入样例
5
输出样例
5
样例说明
①号数 1 个数轮到②号
②号数 2 个数轮到④号
④号数 3 个数轮到②号,继续数到 4 轮到③号
③号数 5 个数轮到③号,继续数到 7 轮到⑤号
数据范围与提示
输入的数据保证小于100。
答案
#include <bits/stdc++.h>
using namespace std;
int vis[110], n, pos, x, cnt;
// pos:当前位置;x:轮次;cnt:已完成拼图的人数
int main() {
cin >> n;
pos = 1; x = 1; vis[1] = 1, cnt = 1; // 基于第一个的状态,去寻找第二位
while (cnt < n) { // 等于 n 代表已寻找结束
pos = 1 + (pos - 1 + x) % n; // 新的位置
while (vis[pos]) { // 循环判断是否已完成拼图
x++; // 轮次增加
pos = 1 + (pos - 1 + 1) % n; // 往后移一位
}
vis[pos] = 1; // 标记访问
cnt++; // 已完成人数增加
x++; // 轮次增加
}
cout << pos;
return 0;
}
· 创队形
时空限制 CPU占用时长: 1秒 内存使用限制: 128MB
题目描述
C 组正在拍创意集体照。老师每次都随机抽 k 个同学搭档,每组搭档都会商量出一款极富创意的独特造型拍照留念(搭档组合不得重复出现,即每组搭档只能拍一张创意照片)。C 组共有 n 个同学,帮助老师计算不同创意照片的张数。
输入格式
两个正整数 n 和 k,中间用空格隔开,含义同题意。
输出格式
一个整数,表示不同创意照片的张数。
输入输出样例
输入样例
4 2
输出样例
6
样例说明
共有{1,2}、{1,3}、{1,4}、{3,2}、{4,2}、{3,4}等同学组合拍出的 6 种不同造型照。
数据范围与提示
输入的数据保证 0<k<n<20。
答案
// 深搜组合经典方法
#include <bits/stdc++.h>
using namespace std;
int n, k, cnt;
void dfs(int dep, int last) {
if (dep == k) { // 搜到 k 个数
cnt++;
return;
}
for (int i = last + 1; i <= n; i++) {
dfs(dep + 1, i);
}
}
int main() {
cin >> n >> k;
dfs(0, 0);
cout << cnt;
return 0;
}
// 方法 2:数学组合公式
// #include <bits/stdc++.h>
// using namespace std;
// int main() {
// int n, k;
// cin >> n >> k;
// long long x = 1, y = 1;
// for (int i = n; i >= n - k + 1; i--) {
// x *= i;
// }
// for (int i = 1; i <= k; i++) {
// y *= i;
// }
// cout << x / y;
// return 0;
// }
巧分配
时空限制 CPU占用时长: 1秒 内存使用限制: 128MB
题目描述
D 组在拔河。同学们不同意按人数平分,而是希望按体重平分成两组。根据小组人员的实际体重(自创计量单位),设计分配方案,使两组体重和的差距最小(两组人数可以不同)。
注意:本题有多组测试。
输入格式
第一行为测试数据组数 T。
针对每组测试数据:
第一行,一个正整数 n,表示小组总人数。
第二行,n 个正整数,中间用空格隔开,表示每个同学的体重。
输出格式
每组测试数据输出一行:
一个非负整数,表示两组体重和的最小差距。
输入输出样例
输入样例
1
9
6 3 1 2 4 8 7 8 9
输出样例
0
数据范围与提示
输入的数据保证 0<T<6,1<n<1000,所有人员体和 ≤100000
答案
// 01 背包问题,容量是总体重的一半,尽量塞满,另一半则自动归为一组
#include <bits/stdc++.h>
using namespace std;
int sum, t, n, m;
int a[1005], dp[100005]; // 注意背包空间不是 1000
int main() {
cin >> t;
while (t--) { // t 组测试
sum = 0;
memset(dp, 0, sizeof(dp)); // 清空 sum 和 dp
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
sum += a[i];
}
m = sum / 2; // 整除 2 是背包的总容量,尽量塞满
for (int i = 1; i <= n; i++) { // 01 背包
for (int j = m; j >= a[i]; j--) {
dp[j] = max(dp[j], dp[j - a[i]] + a[i]);
}
}
cout << sum - dp[m] - dp[m] << endl; // 计算两队的差值,不能用
}
return 0;
}