202412-1 Recamán
题目描述
小杨最近发现了有趣的 Recamán 数列,这个数列是这样生成的:
- 数列的第一项 是 ;
- 如果 是正整数并且没有在数列中出现过,那么数列的第 项 为 ,否则为 。
小杨想知道 Recamán 数列的前 项从小到大排序后的结果。手动计算非常困难,小杨希望你能帮他解决这个问题。
输入格式
第一行,一个正整数 。
输出格式
一行, 个空格分隔的整数,表示 Recamán 数列的前 项从小到大排序后的结果。
样例输入 1
5样例输出 1
1 2 3 6 7样例输入 2
8样例输出 2
1 2 3 6 7 12 13 20提示
【样例解释】
对于样例 1,:
- ;
- ,不是正整数,因此 ;
- ,不是正整数,因此 ;
- ,是正整数,且没有在数列中出现过,因此 ;
- ,不是正整数,因此 。
从小到大排序的结果为 。
【数据范围】
对于所有数据点,保证 。
代码解析
根据题目意思写代码,模拟法解题即可,这里可以把“正整数并且没有在数列中出现过”封装为一个
check()函数,可以让主函数可读性更佳,其余没有什么难点了。
#include<bits/stdc++.h>using namespace std;int n, a[3005];bool check(int num) { if (num <= 0) return false; for (int i = 1; i <= n; i++) if (num == a[i]) return false; return true;}int main() {
a[1] = 1; cin >> n; for (int i = 2; i <= n; i++) if (check(a[i-1] - i)) a[i] = a[i-1] - i; else a[i] = a[i-1] + i; sort(a+1, a+n+1); for (int i = 1; i <= n ; i++) cout << a[i] << ' ';
return 0;}202412-2 字符排序
题目描述
小杨有 个仅包含小写字母的字符串 ,小杨想将这些字符串按一定顺序排列后拼接到一起构成字符串 。小杨希望最后构成的字符串 满足:
- 假设 为字符串 的第 个字符,对于所有的 均有 。两个字符的大小关系与其在字母表中的顺序一致,例如 。
小杨想知道是否存在满足条件的字符串排列顺序。
输入格式
第一行包含一个正整数 ,代表测试数据组数。
对于每组测试数据,第一行包含一个正整数 ,含义如题面所示。
之后 行,每行包含一个字符串 。
输出格式
对于每组测试数据,如果存在满足条件的排列顺序,输出(一行一个),否则输出(一行一个) 。
样例输入 1
33aaacde2aacbc1gesp样例输出 1
100提示
【样例解释】
对于第一组测试数据,一种可行的排列顺序为 ,构成的字符串 为 ,满足条件。
对于全部数据,保证有 ,每个字符串的长度不超过 。
代码解析
题目的意思是,我们需要对于这个字符串数组重新排列,拼接成一个新的字符串,这个字符串里面的字符都需要按照字母表(ASCII 编码)去排序,需要知道能否找到这样的排列方式
思考一下,如果存在这样的排列方式,那么任何一个字符串的字典序一定比前一个字符串的字典序大,所以我们可以先对字符串数组按照字典序排序,然后拼接成新字符串,检查一下拼接后的字符串的每个字符是否大于等于前一个字符即可。
#include<bits/stdc++.h>using namespace std;bool check(string s) { for (int i = 1; i < s.size(); i++) if (s[i-1] > s[i]) return false; return true;}int main() {
int t, n; cin >> t; while (t--) { cin >> n; string a[105], s; for (int i = 0; i < n; i++) cin >> a[i]; sort(a, a+n); for (int i = 0; i < n; i++) s += a[i]; if (check(s)) cout << 1 << endl; else cout << 0 << endl; }
return 0;}202409-1 黑白方块
题目描述
小杨有一个 行 列的网格图,其中每个格子要么是白色,要么是黑色。 小杨想知道网格图中是否存在一个满足如下条件的子矩形:
- 子矩形由 行 列组成;
- 子矩形的第 行和第 行只包含白色格子;
- 对于子矩形的第 行和第 行,只有第 个和第 个格子是白色的,其余格子都是黑色的;
请你编写程序帮助小杨判断。
输入格式
第一行包含一个正整数 ,代表测试用例组数。
接下来是 组测试用例。对于每组测试用例,一共 行。
第一行包含两个正整数 ,含义如题面所示。
之后 行,每行一个长度为 的 串,代表网格图第 行格子的颜色,如果为 ,则对应格子为白色,否则为黑色。
输出格式
对于每组测试用例,如果存在,输出 Yes,否则输出 No。
样例输入 1
31 401105 500000011000110000001011005 50000001100011100000101100样例输出 1
NoYesNo提示
【样例 1 解释】
0000011001100000【数据规模与约定】
对全部的测试数据,保证 ,。
代码解析
这道题也是暴力枚举解题即可,注意有多层循环跳出比较麻烦的话可以多封装几个函数,模块化编写不容易出问题,这道题需要注意的是行列如果小于 4 则不需要进行额外判断,还有多个 if 如果嵌套的话注意加大括号。
#include<bits/stdc++.h>using namespace std;int t, n, m;int a[105][105];bool check4(int i, int j) { for (int x = i; x <= i+3; x++) for (int y = j; y <= j+3; y++) if (x == i || x == i+3) { if (a[x][y] == 1) return false; } else { if (y == j || y == j+3) { if (a[x][y] == 1) return false; } else { if (a[x][y] == 0) return false; } } return true;}bool check() { if (n < 4 || m < 4) return false; // 枚举 4 行 4 列的左上角起点 for (int i = 1; i <= n-3; i++) for (int j = 1; j <= m-3; j++) if (check4(i, j)) return true; return false;}int main() {
cin >> t; while (t--) { cin >> n >> m; for (int i = 1; i <= n; i++) { string s; cin >> s; for (int j = 1; j <= m; j++) a[i][j] = s[j-1] - '0'; } if (check()) cout << "Yes" << endl; else cout << "No" << endl; }
return 0;}202409-2 区间排序
题目描述
小杨有一个包含 个正整数的序列 。
小杨计划对序列进行多次升序排序,每次升序排序小杨会选择一个区间 ()并对区间内所有数字,即进行升序 排序。每次升序排序会在上一次升序排序的结果上进行。
小杨想请你计算出多次升序排序后的序列。
输入格式
第一行包含一个正整数 ,含义如题面所示。
第二行包含 个正整数 ,代表序列 。
第三行包含一个正整数 ,代表排序次数。
之后 行,每行包含两个正整数 ,代表将区间 内所有数字进行升序排序。
输出格式
输出一行包含 个正整数,代表多次升序排序后的序列。
样例输入 1
53 4 5 2 134 53 41 3样例输出 1
1 3 4 5 2提示
【样例 1 解释】
- 第一次升序排序后,序列为 ;
- 第二次升序排序后,序列为 ;
- 第三次升序排序后,序列为 ;
【数据规模与约定】
对于全部的测试数据,保证 ,。
代码解析
很简单的一道题,考察对于 STL sort() 的运用,注意参数即可。
#include<bits/stdc++.h>using namespace std;int main() {
int a[105], n; cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; int q, l, r; cin >> q; while (q--) { cin >> l >> r; sort(a+l, a+r+1); } for (int i = 1; i <= n; i++) cout << a[i] << ' ';
return 0;}202406-1 黑白方块
题目描述
小杨有一个 行 列的网格图,其中每个格子要么是白色,要么是黑色。对于网格图中的一个子矩形,小杨认为它是平衡的当且仅当其中黑色格子与白色格子数量相同。小杨想知道最大的平衡子矩形包含了多少个格子。
输入格式
第一行包含两个正整数 ,含义如题面所示。
之后 行,每行一个长度为 的 串,代表网格图第 行格子的颜色,如果为 ,则对应格子为白色,否则为黑色。
输出格式
输出一个整数,代表最大的平衡子矩形包含格子的数量,如果不存在则输出 。
样例输入 1
4 500000011110001100011样例输出 1
16提示
【样例解释】
对于样例 ,假设 代表第 行第 列,最大的平衡子矩形的四个顶点分别为 。
【数据范围】
对于全部数据,保证有 。
代码解析
暴力枚举解题即可,我们枚举子矩形的左上角的坐标(a, b)以及右下角的坐标(c, d),检查这个矩形中黑白方块的个数是否相同即可,这道题考察的依旧是对题目的理解能力、数组的下标规律以及编写代码的细心程度。
#include<bits/stdc++.h>using namespace std;int n, m, max_cnt = 0;char w[11][11];void check(int a, int b, int c, int d) { int t = 0, f = 0; for (int i = a; i <= c; i++) for (int j = b; j <= d; j++) if (w[i][j] == '1') t++; else f++; if (t == f) { max_cnt = max(max_cnt, (c-a+1)*(d-b+1)); }}int main() {
cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> w[i][j]; for (int a = 1; a <= n; a++) for (int b = 1; b <= m; b++) for (int c = a; c <= n; c++) for (int d = b; d <= m; d++) check(a, b, c, d); cout << max_cnt;
return 0;}202406-2 宝箱
题目描述
小杨发现了 个宝箱,其中第 个宝箱的价值是 。
小杨可以选择一些宝箱放入背包并带走,但是小杨的背包比较特殊,假设小杨选择的宝箱中最大价值为 ,最小价值为 ,小杨需要保证 ,否则小杨的背包会损坏。
小杨想知道背包不损坏的情况下,自己能够带走宝箱的总价值最大是多少。
输入格式
第一行包含两个正整数 ,含义如题面所示。
第二行包含 个正整数 ,代表宝箱的价值。
输出格式
输出一个整数,代表带走宝箱的最大总价值。
样例输入 1
5 11 2 3 1 2样例输出 1
7提示
【样例解释】
在背包不损坏的情况下,小杨可以拿走两个价值为 的宝箱和一个价值为 的宝箱。
【数据范围】
对于全部数据,保证有 ,,。
代码解析
还是枚举啦,小杨的背包中最大价值和最小价值的物品的差是有要求的,我们只需要把物品按照价值从小到大排序,然后确定一个价值最小的物品
a[i],然后累加a[i]之后所有满足a[x] - a[i] <= k的a[x],就可以枚举出一种可能性,再打擂台即可。
#include<bits/stdc++.h>using namespace std;int main() {
int a[1005], n, k, w = 0; cin >> n >> k; for (int i = 0; i < n; i++) cin >> a[i]; sort(a, a+n); for (int i = 0; i < n; i++) for (int j = i; j < n; j++){ int sum = 0; for (int x = i; x <= j; x++) if (a[x] - a[i] <= k) sum += a[x]; w = max(sum, w); } cout << w;
return 0;}如果觉得三层循环枚举时间复杂度太高,也可以使用双指针,如果
a[x] - a[i] <= k则x++,否则i++。记得同步修改sum,注意边界问题。
#include<bits/stdc++.h>using namespace std;int main() {
int a[1005], n, k, w = 0; cin >> n >> k; for (int i = 0; i < n; i++) cin >> a[i]; sort(a, a+n); int i = 0, x = 0, sum = 0; while (x != n) { while (a[x] - a[i] <= k && x < n) { sum += a[x]; x++; } w = max(sum, w); while (a[x] - a[i] > k && i <= x) { sum -= a[i]; i++; } } cout << w;
return 0;}202403-1 相似字符串
题目描述
对于两个字符串 和 ,如果 可以通过删除一个字符,或插入一个字符,或修改一个字符变成 ,那么我们说 和 是相似的。
比如 可以通过插入一个字符变成 ,可以通过删除一个字符变成 ,也可以通过修改一个字符变成 。因此 和 、、 都是相似的。但 并不能 通过任意一个操作变成 ,因此它们并不相似。
特别地,两个完全相同的字符串也是相似的。
给定 组 ,请你分别判断它们是否相似。
输入格式
第一行一个正整数 。
接下来 行,每行两个用空格隔开的字符串 和 。
输出格式
对组 ,如果他们相似,输出 similar,否则输出 not similar。
样例输入 1
5apple appleeapple appeapple bppleapplee bppleapple apple样例输出 1
similarsimilarsimilarnot similarsimilar提示
对全部的测试数据,保证 , 和 的长度不超过 ,仅含小写字母。
代码解析
题目本身不难,判断需要先看两个字符之间的长度差是
0还是1,除他们之外就不可能相似,分情况讨论:
- 如果长度差是
0,则只允许一个字符不相同- 如果长度差是
1,则肯定是多了一位,其他位都相同
#include<bits/stdc++.h>using namespace std;bool is_similar(string s1, string s2) { // 为了方便处理,我们通过交换确保 s1 比 s2 长 if (s1.size() > s2.size()) swap(s1, s2); int sub_size = s2.size() - s1.size(); if (sub_size == 0) { int cnt = 0; for (int i = 0; i < s1.size(); i++) if (s1[i] != s2[i]) cnt++; return cnt <= 1; } else if (sub_size == 1) { for (int i = 0, j = 0; i < s1.size(); i++, j++) if (s1[i] != s2[j]) { j++; if (s1[i] != s2[j]) return false; } return true; } return false;}int main() {
int n; cin >> n; string s1, s2; while (n--) { cin >> s1 >> s2; if (is_similar(s1, s2)) cout << "similar" << endl; else cout << "not similar" << endl; }
return 0;}202403-2 做题
题目描述
小杨同学为了提高自己的实力制定了做题计划,在第 天时,他必须要完成 道题,否则他就会偷懒。
小杨同学现在找到了一个题库,一共有 套题单,每一套题单中有一定数量的题目。但是他十分挑剔,每套题单他只会使用一次,每一天也只能使用一套题单里的题目,之后那套题单就会弃之不用。对于每套题单,他不必完成题单内所有的题。
那么问题来了,小杨同学最多做题几天才偷懒呢?
输入格式
第一行,一个整数为 ,表示有多少套题单。
第二行 个整数 ,分别表示每套题单有多少道题。
输出格式
输出一行一个整数表示答案。
样例输入 1
43 1 4 1样例输出 1
3提示
对全部的测试数据,保证 ,。
代码解析
认真细心即可答对,考点就是数组以及排序,其实也可以说是双指针思路,排好序之后依次尝试,如果卷子
a[i]的题目数量大于天数day则换下一套题下一天,如果题目不够则只换下一套题(i++),最后注意如果最后一天题目不够的话,天数实际上是多一天。
#include<bits/stdc++.h>using namespace std;int main() {
int n, a[1000005], day = 1; cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; sort(a, a+n); for (int i = 0; i < n; i++) if (a[i] >= day) day++; cout << day-1;
return 0;}
陕公网安备61010302001363号