GESP 4级¶
B3939 [GESP样题 四级] 绝对素数¶
B3940 [GESP样题 四级] 填幻方¶
B3850 [GESP202306 四级] 幸运数¶
提示
// 按字符串读入处理
// 数位拆分
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
while (n--) {
string s;
cin >> s;
int sum = 0;
for (int i = s.size() - 1, j = 1; i >= 0; i--, j++) {
int t = s[i] - '0';
if (j % 2) {
t *= 7;
while (t > 9) {
int x = 0;
while (t) {
x += t % 10;
t /= 10;
}
t = x;
}
}
sum += t;
}
if (sum % 8 == 0) cout << 'T' << endl;
else cout << 'F' << endl;
}
return 0;
}
B3851 [GESP202306 四级] 图像压缩-好题 多练¶
提示
// 输入n行偶数长度的字符串,每两位表示一个灰色
// 要统计数量最多的前16种灰色,然后把现有的这些灰色向 选出来的16种靠拢。
// 思路,使用.substr()来拆出来每两位的字符串,map维护出现次数
// 把string,次数,存到一个结构体里,进行自定义排序,选出来前16种
// 重新遍历一遍之前的二维数组,每两位进行替换,替换的过程可以直接枚举16种,和哪个更接近。即可
代码
#include <bits/stdc++.h>
using namespace std;
string g[25], ans[25];
int n;
map<string, int> mp;
string str = "0123456789ABCDEF";
struct node {
string s;
int cnt;
}a[300];
int to_num(string s) {
return str.find(s[0]) * 16 + str.find(s[1]);
}
bool cmp(node a, node b) {
if (a.cnt != b.cnt) return a.cnt > b.cnt;
return a.s < b.s;
}
char check(string s) {
int ret = 0;
int delta = 0x3f3f3f3f;
for (int i = 0; i < 16; i++) {
int t = abs(to_num(s) - to_num(a[i].s));
if (t < delta) {
delta = t;
ret = i;
}
}
return str[ret];
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) cin >> g[i];
for (int i = 0; i < n; i++) {
for (int j = 0, len = g[i].size(); j < len; j += 2) {
string t = g[i].substr(j, 2);
mp[t]++;
}
}
int idx = 0;
for (auto x : mp) {
a[idx].s = x.first, a[idx].cnt = x.second;
idx++;
}
sort(a, a + idx, cmp);
for (int i = 0; i < n; i++) {
for (int j = 0, len = g[i].size(); j < len; j += 2) {
string t = g[i].substr(j, 2);
ans[i] += check(t);
}
}
for (int i = 0; i < 16; i++) cout << a[i].s;
puts("");
for (int i = 0; i < n; i++) cout << ans[i] << '\n';
return 0;
}
B3869 [GESP202309 四级] 进制转换¶
代码
B3870 [GESP202309 四级] 变长编码-好题¶
提示
// 新定义,变长编码。
// 先转成二进制
// 每组7bit,划分成不同的组
// 从低位的每组开始,填补上第8位bit。如果是最高位的组,补0;其他补1
// 输出每一组,转换成2位16进制数,用空格隔开。
代码
#include <bits/stdc++.h>
using namespace std;
int a[100], idx;
string str = "0123456789ABCDEF";
int main() {
long long n;
cin >> n;
if (n == 0) a[0] = 0, idx = 1;
while (n) {
a[idx++] = n % 2;
n /= 2;
}
for (int i = 0; i < idx; i += 7) {
int t[10];
for (int j = 0; j < 7; j++)
if (i + j < idx) t[j] = a[i + j];
else t[j] = 0;
if (i + 7 < idx) t[7] = 1;
else t[7] = 0;
int x = t[0] + t[1] * 2 + t[2] * 4 + t[3] * 8;
int y = t[4] + t[5] * 2 + t[6] * 4 + t[7] * 8;
cout << str[y] << str[x] << ' ';
}
return 0;
}
提示02
// 官方题解给的示范代码,是用位运算来获取每7位的,& 0x7f
// 将第8位赋值成1,按位或,| 80
// 输出两位16进制数的时候,也采用了 &0x07 >>=4 这种操作
// 比较巧妙,学习了。代码比我这个简便
代码02
#include <bits/stdc++.h>
using namespace std;
int split[10], idx;
long long n;
string str = "0123456789ABCDEF";
int main() {
cin >> n;
if (n == 0) split[idx++] = 0;
while (n) {
split[idx++] = n & 0x7F;
n >>= 7;
}
// 第8位置成 1
for (int i = 0; i < idx - 1; i++) split[i] |= 0x80;
for (int i = 0; i < idx; i++) {
cout << str[split[i] >> 4] << str[split[i] & 0x0F] << ' ';
}
return 0;
}
B3927 [GESP202312 四级] 小杨的字典¶
提示
// 有翻译就翻,没有就输出UNK
// 抠单词,map
代码
#include <bits/stdc++.h>
using namespace std;
map<string, string> mp;
int main() {
int n;
cin >> n;
while (n--) {
string a, b;
cin >> a >> b;
mp[a] = b;
}
string s;
cin >> s;
for (int i = 0, len = s.size(); i < len; i++) {
if (!(s[i] >= 'a' && s[i] <= 'z')) {cout << s[i]; continue;}
string t;
int j = i;
while (j < len && s[j] >= 'a' && s[j] <= 'z') t += s[j++];
if (mp.count(t) == 0) cout << "UNK";
else cout << mp[t];
// 此时j是第一个不是单词的位置
i = j - 1;
}
return 0;
}
B3928 [GESP202312 四级] 田忌赛马¶
提示
贪心
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N], n;
int main() {
cin >> n;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
sort(a + 1, a + 1 + n);
sort(b + 1, b + 1 + n);
int ret = 0;
for (int i = 1, j = 1; i <= n; i++)
if (a[i] > b[j]) ret++, j++;
cout << ret;
return 0;
}
B3958 [GESP202403 四级] 相似字符串-好题¶
提示
// 长度一样,看不同的元素 是否<=1
// 长度相差1,就看少一个能不能匹配上(这个不好操作)
// 长度相差>1,直接不可能
// 长度相差1,用短去比大的,可能是子串,也可能是中间断开
// 中间断开的情况,就判断当前字符不同,如果和下一位也不同,就结束。
// 如果和下一位下同,则后面的所有字符都要相同
提示2
// 长度一样:
// 完全一样 s1 == s2
// 有一个不一样 for一遍看几个不一样
// 长度差1个:短的是长的一部分
// xxxxx. .find()
// .xxxxx
// xxx.xx 模拟一遍
代码
#include <bits/stdc++.h>
using namespace std;
int T;
string a, b;
bool check() {
int lena = a.size(), lenb = b.size();
if (abs(lena - lenb) > 1) return false;
if (lena == lenb) {
int cnt = 0;
for (int i = 0; i < lena; i++) if (a[i] != b[i]) cnt++;
return cnt <= 1;
}
else {
if (lena > lenb) swap(a, b), swap(lena, lenb);
int cnt = 0, i = 0, j = 0;
while (i < lena && j < lenb) {
if (a[i] != b[j]) cnt++, j++;
else i++, j++;
}
return cnt <= 1;
}
return false;
}
int main() {
cin >> T;
while (T--) {
cin >> a >> b;
if (check()) cout << "similar" << endl;
else cout << "not similar" << endl;
}
return 0;
}
B3959 [GESP202403 四级] 做题¶
提示
// 排序,然后从前往后,贪心的选取
// 如果当前题目不够第i天使用的,就往后看
代码
B4005 [GESP202406 四级] 黑白方块¶
提示
// n,m <= 10,直接枚举所有子矩阵,\(O(n^6)\)
// 字符串读入
// 有类似问题,枚举所有子矩阵
代码
#include <bits/stdc++.h>
using namespace std;
string s[20];
int n, m, maxn;
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> s[i];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
for (int i2 = i; i2 < n; i2++)
for (int j2 = j; j2 < m; j2++) {
int one = 0, zero = 0;
for (int p = i; p <= i2; p++)
for (int q = j; q <= j2; q++)
if (s[p][q] == '0') zero++;
else one++;
if (one == zero) maxn = max(maxn, one + zero);
}
cout << maxn;
return 0;
}
B4006 [GESP202406 四级] 宝箱¶
提示
//保证价值对大切,x - y <= k;
代码
#include <bits/stdc++.h>
using namespace std;
int a[1010];
int tmp;
int main(){
int n, k;
cin >> n >> k;
for(int i = 0 ; i < n; i++){
cin >> a[i];
}
sort(a, a + n);
for(int i = 0 ; i < n; i++){
int j = 0;
int sum = 0;
while(abs(a[i] - a[i + j]) <= k && i + j < n){
sum += a[i + j];
j++;
}
if(sum > tmp) tmp = sum;
}
cout << tmp << '\n';
return 0;
}
B4040 [GESP202409 四级] 黑白方块¶
提示
// 写一个check函数
代码
#include <bits/stdc++.h>
using namespace std;
char s[110][110];
int a[110][110], n, m, T;
bool check(int x, int y) {
for (int j = y; j < y + 4; j++) if (a[x][j] || a[x + 3][j]) return false;
for (int i = x; i < x + 4; i++) if (a[i][y] || a[i][y + 3]) return false;
if (!a[x + 1][y + 1] || !a[x + 1][y + 2] || !a[x + 2][y + 1] || !a[x + 2][y + 2]) return false;
return true;
}
int main() {
cin >> T;
while (T--) {
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> s[i];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) a[i][j] = s[i][j] - '0';
bool flag = false;
for (int i = 0; i < n - 3 && !flag; i++)
for (int j = 0; j < m - 3 && !flag; j++) {
if (check(i, j)) flag = true;
}
if (flag) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
B4041 [GESP202409 四级] 区间排序¶
提示
// 用sort排序
代码
B4068 [GESP202412 四级] Recamán¶
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
int a[N], n;
map<int, int> mp;
int main() {
cin >> n;
a[1] = 1;
mp[1] = 1;
for (int i = 2; i <= n; i++) {
int t = a[i - 1] - i;
if (t > 0 && mp.count(t) == 0) a[i] = t;
else a[i] = a[i - 1] + i;
mp[a[i]] = 1;
}
sort(a + 1, a + 1 + n);
for (int i = 1; i <= n; i++) cout << a[i] << ' ';
return 0;
}
B4069 [GESP202412 四级] 字符排序¶
提示
// 对字符串进行排序,然后枚举一遍,是否满足升序的关系
代码
#include <bits/stdc++.h>
using namespace std;
int T, n;
string s[110];
int main() {
cin >> T;
while (T--) {
cin >> n;
for (int i = 0; i < n; i++) cin >> s[i];
sort(s, s + n);
string t;
for (int i = 0; i < n; i++) t += s[i];
bool flag = false;
for (int i = 1, len = t.size(); i < len; i++)
if (t[i - 1] > t[i]) {flag = true; break;}
if (flag) cout << 0 << endl;
else cout << 1 << endl;
}
return 0;
}
B4263 [GESP202503 四级] 荒地开垦-代码难度较大¶
提示
// n,m <= 1000
// 这个题目读题上,会有一点困难,得理解理解让我们干什么
// 先把所有肯定可以开垦的统计处理
// 维护一遍,每一个杂物的位置,如果去掉它,可以增加几个可以开垦的荒地。打擂台求一个最值
// 答案就是,肯定能开垦的+新增的delta
// 写了一发,这个感觉代码实现,很费劲
代码
#include <bits/stdc++.h>
using namespace std;
string s[1010];
int n, m, cnt, maxn;
int check(int i, int j) {
if (i < 0 || i >= n || j < 0 || j >= m) return 1;
if (s[i][j] == '#') return 1;
if (!(i == 0 || (i >= 1 && s[i - 1][j] == '.'))) return 1;
if (!(i == n - 1 || (i < n - 1 && s[i + 1][j] == '.'))) return 1;
if (!(j == 0 || (j >= 1 && s[i][j - 1] == '.'))) return 1;
if (!(j == m - 1 || (j < m - 1 && s[i][j + 1] == '.'))) return 1;
return 0;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> s[i];
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (s[i][j] == '.') {
if (!check(i, j)) cnt++;
}
else {
int sum = 0;
s[i][j] = '.';
if (!check(i, j)) sum++;
if (!check(i - 1, j)) sum++;
if (!check(i + 1, j)) sum++;
if (!check(i, j - 1)) sum++;
if (!check(i, j + 1)) sum++;
maxn = max(maxn, sum);
s[i][j] = '#';
}
cout << cnt + maxn;
return 0;
}
B4264 [GESP202503 四级] 二阶矩阵¶
提示
// 二维数组的枚举
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 510;
int a[N][N], n, m, cnt;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) cin >> a[i][j];
for (int i = 1; i < n; i++)
for (int j = 1; j < m; j++) {
if (a[i][j] * a[i + 1][j + 1] == a[i][j + 1] * a[i + 1][j]) cnt++;
}
cout << cnt;
return 0;
}
B4360 [GESP202506 四级] 画布裁剪¶
提示
// 二维字符数组的读入(要注意正确的读入方式)
// 注意变量命名y1的问题,下标从0开始的问题
// 注意输入顺序
代码
B4361 [GESP202506 四级] 排序¶
提示
// 定义结构体比较关系,用冒泡求逆序对
// 身高从高到低,体重从重到轻
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 3010;
struct node{
int h, w;
}a[N];
int n, cnt;
bool check(int i, int j) {
if (a[i].h < a[j].h) return true;
if (a[i].h == a[j].h) return a[i].w < a[j].w;
return false;
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i].h >> a[i].w;
for (int i = 0; i < n; i++)
for (int j = 0; j < n - 1; j++)
if (check(j, j + 1)) swap(a[j], a[j + 1]), cnt++;
cout << cnt;
return 0;
}
B4415 [GESP202509 四级] 排兵布阵¶
提示
// n,m<=12,直接枚举
// n^2 * n^2 * n^2
代码
#include <bits/stdc++.h>
using namespace std;
int a[20][20], n, m;
int maxn;
int s[20][20];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) cin >> a[i][j];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
for (int i2 = i; i2 <= n; i2++)
for (int j2 = j; j2 <= m; j2++) {
int cnt = s[i2][j2] - s[i - 1][j2] - s[i2][j - 1] + s[i - 1][j - 1];
if (cnt == (i2 - i + 1) * (j2 - j + 1)) maxn = max(maxn, cnt);
}
cout << maxn;
return 0;
}
B4416 [GESP202509 四级] 最长连续段¶
提示
排序,去重
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N], n;
int main() {
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n);
int p = 1;
for (int i = 1; i < n; i++)
if (a[i] != a[i - 1]) a[p++] = a[i];
n = p;
// for (int i = 0; i < n; i++) cout << a[i] << ' ';
int cnt = 1, maxn = 1;
for (int i = 1; i < n; i++) {
if (a[i] == a[i - 1] + 1) {
cnt++;
maxn = max(maxn, cnt);
}
else cnt = 1;
}
cout << maxn;
return 0;
}
代码02
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
int main() {
cin >> n;
vector<int> A(n);
for (int i = 0; i < n; i++) cin >> A[i];
sort(A.begin(), A.end());
A.erase(unique(A.begin(), A.end()), A.end());
int cnt = 1, maxn = 1;
for (int i = 1, n = A.size(); i < n; i++) {
if (A[i] == A[i - 1] + 1) {
cnt++;
maxn = max(maxn, cnt);
}
else cnt = 1;
}
cout << maxn;
return 0;
}
B4451 [GESP202512 四级] 建造¶
代码
#include <bits/stdc++.h>
using namespace std;
int m, n, h;
int a[1010][1010];
int ans;
int main() {
cin >> m >> n >> h;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++) cin >> a[i][j];
for (int i = 1; i <= m - 2; i++)
for (int j = 1; j <= n - 2; j++) {
int maxn = -1, minn = 2e9, sum = 0;
for (int ii = i; ii <= i + 2; ii++)
for (int jj = j; jj <= j + 2; jj++) {
maxn = max(maxn, a[ii][jj]);
minn = min(minn, a[ii][jj]);
sum += a[ii][jj];
}
if (maxn - minn <= h) ans = max(ans, sum);
}
cout << ans;
return 0;
}
B4452 [GESP202512 四级] 优先购买¶
提示
//小明有m元,商店有n个商品,卖东西的规律为:
//总是优先买优先级最高的东西;
//有多个最高优先级商品,购买价格最低的;
//有多个优先级最高且价格最低的商品,购买商品名字典序最小的。
//满足要求的,按字典序从小到大输出。
//利用结构体和自定义排序,将所有物品排好序,最后根据m循环统计输出
提示02
这个题面有点歧义
没有说明每个优先级是否只允许购买一份(按测试点情况看,可以买多份)