ACGO欢乐赛#52|非官方题解
2025-07-28 20:33:03
发布于:浙江
非官方题解哦,官方题解
比赛题目
T1.修改数字
知识点:多重单分支,双分支
题目:
小明很喜欢数字 1, 2, 3。 现在他获得了三个数字 a, b, c, 他可以进行最多一次操作,将其中一个数字变成任意数字。请问经过最多一次操作之后,三个数字 a, b, c 能否变成 1, 2, 3 (a, b, c顺序不能改变) 。
可以的话输出 YES, 否则输出 NO 。
简化:
其实就是 a,b,c 中有 2 个以上的数是 对 的即是 可以 ,否则为 不可以。
俺的方法:
和简化一样,就是记录 a,b,c 中对的数有几个,大于 2 输出YES,否则输出 NO 。
#include <bits/stdc++.h>
using namespace std;
int main(){
int a,b,c;
cin >> a >> b >> c;
int AC = 0; // 记录对的个数
if(a == 1) AC++; // a 对,AC加一
if(b == 2) AC++; // b 对,AC加一
if(c == 3) AC++; // c 对,AC加一
if(AC >= 2) cout << "YES"; // AC(对的)大于 2 输出 YES
else cout << "NO"; // 否则输出 NO。
return 0;
}
实在不会,你暴力判断也能过:
#include <bits/stdc++.h>
using namespace std;
int main(){
int a,b,c;
cin >> a >> b >> c;
if(a == 1 && b == 2) cout << "YES"; // 更改的是 c
else if(a == 1 && c == 3) cout << "YES"; // 更改的是 b
else if(b == 2 && c == 3) cout << "YES"; // 更改的是 a
else cout << "NO"; // 更改后也无法做到
return 0;
}
T2.小明的非递减数组
知识点: 单分支,for循环,一维数组
题目:
给定一个长度为 n 的数组 a, 现在小明可以对数组进行操作, 每次操作可以选择一个数字 i (1 ≤ i ≤ n) ,使得 加 1。请问最少经过几次操作可以使得数组变成一个非递减数组。
非递减数组 : 对于任意的数字 对于任意的数字 i (2 ≤ i ≤ n) , 都满足 ≤ 。
简化:
其实就是经过几次+1可以是 a 数组成为一个 非递减数组 。
俺的方法:
比较 是否大于 ,如果大于 就说明这成不了 非递减数组,所以要更改这个值,同时计数;否则……没有否则。
#include <bits/stdc++.h>
using namespace std;
int main(){
long long n;
cin >> n;
long long a[n + 5];
for(int i = 1;i <= n;i++){
cin >> a[i];
}
long long ans = 0; // 记得开 long long 和 初始化乘 0 哦!
for(int i = 2;i <= n;i++){
if(a[i - 1] > a[i]){ // 如果 a[i - 1] > a[i] 了,就说明这成不了一个 非递减数组,所以要改这个值,同时计数。
ans += a[i - 1] - a[i];
a[i] = a[i - 1]; // 更改这个数。
}
}
cout << ans;
return 0;
}
T3.小明和视疲劳
知识点: 格式化输入,单分支,字符串,for循环
题目:
小明由于近期用眼过度,出现了很严重的视疲劳,具体表现是分不清大小写字母。
现在给你两个只包含大小写字母和空格的字符串 s, t (1≤∣s∣,∣t∣≤ ),如果它们在小明眼里一样的话,输出 YES, 否则输出 NO。
俺的两种方法:
1.就是比字母嘛,先将字符串中的字母转成大写,再比俩字符串中的第 i 个的字母是否一样,不一样输出 NO,如果全都一样那就输出YES。
2.比较特殊,难懂,就是比较两个数组的第i个元素,这时会遇到两种情况:
- 都是 大写 或 小写,这时候它们俩相减(ASCLL码)为0
- 一个是 大写,一个是 小写,这时候它们俩相减(ASCLL码)为32
- 如果都不满足,那么输出 NO
#include <bits/stdc++.h>
using namespace std;
int main(){
string s,t;
getline(cin,s); // 带空格输入
getline(cin,t); // 带空格输入
if(s.size() != t.size()){ // 长度不同比个蛋~呐!
cout << "NO";
return 0;
}
for(int i = 0;i < s.size();i++){
if(abs((int)s[i] - (int)t[i]) != 0 && abs((int)s[i] - (int)t[i]) != 32){
// 比较两个数组的第i个元素,这时会遇到两种情况:
// 都是 大写 或 小写,这时候它们俩相减(ASCLL码)为0
// 一个是 大写,一个是 小写,这时候它们俩相减(ASCLL码)为32
// 如果都不满足,那么输出NO
cout << "NO";
return 0;
}
}
cout << "YES";
return 0;
}
看不懂的话,你把小写转大写好了。
#include <bits/stdc++.h>
using namespace std;
char zdx(char x){ // 手写 转大写 函数
if('A' <= x && x <='Z'){
return x;
} else {
return (char)((int)(x - 32));
}
}
int main(){
string s,t;
getline(cin,s); // 带空格输入
getline(cin,t); // 带空格输入
if(s.size() != t.size()){ // 长度不同比个蛋~呐!
cout << "NO";
return 0;
}
for(int i = 0;i < s.size();i++){
if(toupper(s[i]) != toupper(t[i])){ // 用函数转
cout << "NO";
return 0;
}
}
cout << "YES";
return 0;
}
T4.卡牌
知识点:多分支,while循环
题目:
小明现在手上有这样一副特殊的卡牌, 其中一共有四种卡牌:
a 张数值是 1 的卡牌, b 张数值是 2 的卡牌, c 张数值是 3 的卡牌, d 张数值是 4 的卡牌。
现在小明可以从中选取 k 张卡牌, 请问这 k 张卡牌的数值总和的最大值是多少?
俺的方法:
就是尽可能那大的,拿不了最大的,就拿次大的;拿不了次大的,就拿再次大的……直到 k 为 0 或 a,b,c,d 都为 0 结束。
#include <bits/stdc++.h>
using namespace std;
int main(){
int a,b,c,d,k;
cin >> a >> b >> c >> d >> k;
long long ans = 0; //记得开long long
while(k != 0){ // 重复执行 k 次
if(d > 0){ // 如果可以取 d,那么取一个 d,并且 ans += 4
ans += 4;
d--;
k--;
} else if(c > 0){ // 如果不可以取 d,可以取 c,那么取一个 c,并且 ans += 3
ans += 3;
c--;
k--;
} else if(b > 0){ // 如果不可以取 d,不可以取 c,可以取 b,那么取一个 b,并且 ans += 2
ans += 2;
b--;
k--;
} else if(a > 0){ // 如果不可以取 d,不可以取 c,不可以取 b,可以取 a,那么取一个 a,并且 ans += 1
ans += 1;
a--;
k--;
}
}
cout << ans;
return 0;
}
T5.小明和九宫格
知识点:单分支,for循环,二维数组,函数
题目:
小明有一个很喜欢的九宫格,3 行 3 列一共 9 个数字。
现在给定一个 n 行 m 列的二维矩阵 a, 请问其中是否存在一个子矩阵和小明喜欢的九宫格相等, 存在的话输出 YES, 否则输出 NO。
简化:
就是再 a 数组里找数组 b.
俺的方法:
暴力查找,直接AC。
#include <bits/stdc++.h>
using namespace std;
int n,m;
int a[1010][1010];
int b[5][5];
// bool pd(int x,int y){ // 暴力判断是否一样(AC)
// if(a[x][y] == b[1][1] &&
// a[x][y + 1] == b[1][2] &&
// a[x][y + 2] == b[1][3] &&
// a[x + 1][y] == b[2][1] &&
// a[x + 1][y + 1] == b[2][2] &&
// a[x + 1][y + 2] == b[2][3] &&
// a[x + 2][y] == b[3][1] &&
// a[x + 2][y + 1] == b[3][2] &&
// a[x + 2][y + 2] == b[3][3]) return true;
// return false;
// }
bool pd(int x,int y){ // 循环判断是否一样(AC)
int bx = 1,by = 1;
for(int i = x;i <= x + 2;i++){
for(int j = y;j <= y + 2;j++){
if(a[i][j] != b[bx][by]){
return false;
}
by++;
}
bx++;
by = 1;
}
return true;
}
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 <= 3;i++){
for(int j = 1;j <= 3;j++){
cin >> b[i][j];
}
}
//比较,输出
for(int i = 1;i <= n - 2;i++){
for(int j = 1;j <= m - 2;j++){
if(pd(i,j)){ //判断
cout << "YES";
return 0;
}
}
}
cout << "NO";
return 0;
}
T6.进制转换
做这道题,你可以看一下这个
知识点:双分支,for循环,do-while循环,函数,动态数组,反转数组
题目:
给定两个十进制数字 a, b 和一个数字 r(2≤r≤36)。
对于数字 a 和 b, 将其转化为 r 进制数, 在 r 进制中,大于等于 1010 的数字使用 A-Z 的字母进行表示。
将两个数字转化为 r 进制以后, 输出其中字典序较大的一个数。
直言啦,就是用这个中的 ZS_D_n()
即可完成了。
俺的方法:
将 a, b 转成 r 进制,再存在俩 string 里,然后判断输出
#include<bits/stdc++.h>
using namespace std;
string ZS_D_n(int q, int s){ //十进制转N进制(整数)
vector<char> ve;
do {
if(q > 10 && s % q > 9){
ve.push_back('A' + s % q - 10);
} else {
ve.push_back(s % q + '0');
}
s /= q;
} while(s);
reverse(ve.begin(),ve.end()); //反转数组
string sum = "";
for(int i = 0;i < ve.size();i++){
sum += ve[i];
}
return sum;
}
int main(){
int a,b,r;
cin >> a >> b >> r;
string sum1 = ZS_D_n(r,a);
string sum2 = ZS_D_n(r,b);
if(sum1 > sum2) cout << sum1;
else cout << sum2;
return 0;
}
对你有帮助吗?能给我一个小赞嘛?
恭喜你完成了所有题目!太棒啦!我祝大家每题AC!大家一起加油!
打个广告吧!
拜拜!
@AC君,虽然是非官方题解,但还是求个顶吧!
全部评论 6
顶顶顶
2天前 来自 广东
16
2天前 来自 浙江
0
#include<bits/stdc++.h> using namespace std; int main(){ int a,b,c; cin>>a>>b>>c; if(a==1&&b==2||a==1&&b==3||a==1&&c==2||a==1&&c==3||b==2&&c==3||b==3&&c==2||b==1&&c==3){ cout<<"YES"; }else { cout<<"NO"; } return 0; }
第一个也可以这样写
2天前 来自 浙江
0咋了?
昨天 来自 浙江
0这不就是T1的第二种写法吗?
昨天 来自 浙江
0
谢谢@𝓢𝓷𝓾𝓰𝓰𝓵𝓮的赞
2天前 来自 浙江
0谢谢@🐱🚀的赞
2天前 来自 浙江
0谢谢@司霆惊蛰~的赞
2天前 来自 浙江
0谢
2天前 来自 浙江
0
ddd
2天前 来自 浙江
06
2天前 来自 浙江
07
2天前 来自 浙江
0
有帮助,赞一个