欢乐赛#44非官方全题解
2025-04-08 17:28:53
发布于:北京
本次比赛的题目比较
水简单,所以作者有些题目写的是Python
。但也灰常银性的给出了C++
代码。
一、O
这么简单,不会有人没过吧~
看题,在所有的数字中,只有 8
是有两个 0
的。
在 1 - 100
中,含有 8
最多的是 88
,所以直接输出。
Python Code:
print (88)
C++ Code:
#include <iostream>
int main ()
{
//main;
std::cout << 88 << std::endl;
return 0;
}
二、形图
上来我就看见了“约数”二字,我们直接手搓一个函数:
def is_cd (x, y):
return y % x == 0
这个函数用来判断一个数是不是另一个数的约数。
接下来,我用一个变量来记录当前的 形图
:
num = 17
因为在 i == 0
的时候是没有 形图
的,所以我把他设成了大于 13
且最小的质数。
循环部分:
for i in range (n):
if i != 0 and is_cd (a[i], num):
cnt += 1
#print (i, num, end = ' ')
#print ()
num = a[i]
这里我发现了一个小问题,如果 a[0] == 1
的话,cnt
就会多一,所以我直接写了一个特判。
最后记得输出 cnt
。
Python Code:
def is_cd (x, y):
return y % x == 0
n = int (input ())
a = list (map (int, input ().split ()))
num = 17
cnt = 0
for i in range (n):
if i != 0 and is_cd (a[i], num):
cnt += 1
#print (i, num, end = ' ')
#print ()
num = a[i]
print (cnt)
C++ Code:
#include <bits/stdc++.h>
const int N = 2e5 + 10;
bool is_cd (int x, int y)
{
return y % x == 0;
}int main ()
{
//main;
int n; std::cin >> n;
int a[N] {};
for (int i = 0; i < n; ++ i)
std::cin >> a[i];
int num = 17, cnt = 0;
for (int i = 0; i < n; ++ i)
{
if (i >= 1 and is_cd (a[i], num))
cnt ++;
num = a[i];
}std::cout << cnt << std::endl;
return 0;
}
三、罚时计算
先写一个输入:
int n, m; std::cin >> n >> m;
int a[M][M] {};
for (int i = 0; i < n; ++ i)
for (int j = 0; j < m; ++ j)
std::cin >> a[i][j];
来看一下罚时规则:
- 第一次不算
- 从第二次开始,一次20分钟
那么,提交错误次数
就等于 提交次数
减去 1
,考虑到都是AK,所以没有特殊情况。
那么,计算一个人的罚时的代码就是:
int ans = 0;
for (int j = 0; j < m; ++ j)
ans += a[i][j] * 20 - 20;
为了好写,我们可以利用 乘法分配律
, 将 -1 * 20
提取出来。
注意,要求是计算每个人的罚时,所以每次都要输出,再加上一个循环。
C++ Code:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, M = 1e2 + 10;
void solve ()
{
//main;
int n, m; std::cin >> n >> m;
int a[M][M] {};
for (int i = 0; i < n; ++ i)
for (int j = 0; j < m; ++ j)
std::cin >> a[i][j];
//计算.
for (int i = 0; i < n; ++ i)
{
int ans = 0;
for (int j = 0; j < m; ++ j)
ans += a[i][j] * 20 - 20;
std::cout << ans << ' ';
}return ;
}int main ()
{
//main;
int T = 1; //cin >> T;
while (T --)
solve ();
return 0;
}
四、困难的字符串改造问题
先写输入。
注意,字符串中含有空格,所以需要使用按行输入的函数进行读取。这里我推荐大家使用 std::getline ()
函数,如下:
std::string s;
std::getline (std::cin, s);
而空格位置上要替换的字母由这是第几个空格来决定,所以我们可以使用 cnt
变量,用来记录当前是第几个空格。
如果当前字符是空格,那么 cnt ++;
,然后进行替换,这里我使用了 static_cast <char> ()
函数,其功能是将给定的 ASCII
码转换成其所对应的字符。
考虑到要转换的是大写字母,所以 cnt += 'A'
,这里注意:为了防止超出范围,我们需要对其进行取模。我写的 cnt
是从 1
开始的,所以还需要减 1
。为了简洁,我写了一个函数:
char num_to_let (int x)
{
int asc = x % 26 + 'A' - 1;
char ans = static_cast <char> (asc);
return ans;
}
这里我发现了一个小问题,当 x
等于26时,它返回的是 @
, 而不是 Z
,不知为何,懂的给我讲一下,所以我直接写了一个特判:
char num_to_let (int x)
{
int asc = x % 26 + 'A' - 1;
char ans = static_cast <char> (asc);
return (ans == '@'? 'Z' : ans);
}
主函数部分怎么写,上面说过了,就是简单的把字符串 s
遍历一遍,是空格就转换,计数器加 1。
C++ Code:
#include <bits/stdc++.h>
//using namespace std;
const int N = 1e5 + 10, M = 1e2 + 10;
char num_to_let (int x)
{
int asc = x % 26 + 'A' - 1;
char ans = static_cast <char> (asc);
return (ans == '@'? 'Z' : ans);
}void solve ()
{
//main;
std::string s; std::getline (std::cin, s);
int cnt = 1;
int len = (int) s.length ();
for (int i = 0; i < len; ++ i)
{
if (s[i] == ' ')
{
s[i] = num_to_let (cnt);
cnt ++;
}
}std::cout << s << std::endl;
return ;
}int main ()
{
//main;
int T = 1; //cin >> T;
while (T --)
solve ();
return 0;
}
五、追求更多的玫瑰花
作者第一眼就觉得一定不是暴力。
有一个很明显的点,a[i]
不是 -1
就是 1
,要求加起来是 0,那么,这两种数的个数一定是一样的,总数是 2n
个,这里 n
指的是 -1
的个数(也可以是 1
的个数)。这个总数一定是个偶数。
所以,如果选中数字的数量是个奇数,那么一定是"sad"。
刚才说过,只有这两种数的个数足够使他们一样,才是"happy",否则就是"sad"。
这代码不就出来了?
Python Code:
n, m = map (int, input ().split ())
a = list (map (int, input ().split ()))
cnt_x = 0
cnt_y = 0
for i in range (n):
if a[i] == 1:
cnt_x += 1
else:
cnt_y += 1
#print (cnt_x, cnt_y, end = ' ')
for _ in range (m):
l, r = map (int, input ().split ())
if (r - l) % 2 == 0:
print ("sad")
continue
num = (r - l + 1) // 2
if cnt_x >= num and cnt_y >= num:
print ("happy")
else:
print ("sad")
代码中的注释是作者调试的时候用的,不影响整体代码。
C++ Code:
#include <bits/stdc++.h>
#define Ll long long
//using namespace std;
const int N = 2e5 + 10, M = 1e2 + 10;
void solve ()
{
//main;
int n, m; std::cin >> n >> m;
int a[N] {};
for (int i = 0; i < n; ++ i)
std::cin >> a[i];
//预处理.
int cnt_x = 0, cnt_y = 0;
for (int i = 0; i < n; ++ i)
{
if (a[i] == 1)
cnt_x ++;
else
cnt_y ++;
}while (m --)
{
int l, r; std::cin >> l >> r;
if ((r - l) % 2 == 0)
{
std::cout << "sad" << std::endl;
continue;
}int num = (r - l + 1) / 2;
if (cnt_x >= num and cnt_y >= num)
std::cout << "happy" << std::endl;
else
std::cout << "sad" << std::endl;
}return ;
}int main ()
{
//main;
int T = 1; //cin >> T;
while (T --)
solve ();
return 0;
}
六、进制转换
进制转换怎么写我就不多讲了,网上一抓一大把 (主要因为作者比较懒),这里我用的是 除n取余,倒序读取
的方法:
std::string q = "0123456789ABCDEF";
std::string ten_n (int n, int x)
{
std::string s;
while (x)
{
s = q[x % n] + s;
x = x / n;
}return s;
}
然后我们简简单单写个输入,再把所有的 8 进制数都算好,如下:
int n; std::cin >> n;
int a[N] {};
for (int i = 0; i < n; ++ i)
std::cin >> a[i];
std::string b[N] {};
for (int i = 0; i < n; ++ i)
b[i] = ten_n (8, a[i]);
再来个排序:
std::sort (b + 0, b + n, cmp);
这里的 cpm
函数比较难写,所以我们一步一步来。
题目中要求“先比最低位”,那我们就按照它说的写:
bool cmp (std::string x, std::string y)
{
int len_x = (int) x.length ();
int len_y = (int) y.length ();
if (x[len_x - 1] != y[len_y - 1])
return x[len_x - 1] > y[len_y - 1];
}
最低位相同,“直接从小到大比”:
bool cmp (std::string x, std::string y)
{
int len_x = (int) x.length ();
int len_y = (int) y.length ();
if (x[len_x - 1] != y[len_y - 1])
return x[len_x - 1] > y[len_y - 1];
if (len_x != len_y)
return len_x < len_y;
return x < y;
}
这里注意,由于数据类型是 std::string
,所以要自己写比较方法:先比位数,再比字典序。
最后再来个输出:
for (int i = 0; i < n; ++ i)
std::cout << b[i] << ' ';
C++ Code:
#include <bits/stdc++.h>
#define Ll long long
//using namespace std;
const int N = 2e5 + 10, M = 1e2 + 10;
std::string q = "0123456789ABCDEF";
std::string ten_n (int n, int x)
{
std::string s;
while (x)
{
s = q[x % n] + s;
x = x / n;
}return s;
}bool cmp (std::string x, std::string y)
{
int len_x = (int) x.length ();
int len_y = (int) y.length ();
if (x[len_x - 1] != y[len_y - 1])
return x[len_x - 1] > y[len_y - 1];
if (len_x != len_y)
return len_x < len_y;
return x < y;
}void solve ()
{
//main;
int n; std::cin >> n;
int a[N] {};
for (int i = 0; i < n; ++ i)
std::cin >> a[i];
std::string b[N] {};
for (int i = 0; i < n; ++ i)
b[i] = ten_n (8, a[i]);
/*for (int i = 0; i < n; ++ i)
std::cout << b[i] << ' ';*/
std::sort (b + 0, b + n, cmp);
for (int i = 0; i < n; ++ i)
std::cout << b[i] << ' ';
return ;
}int main ()
{
//main;
int T = 1; //cin >> T;
while (T --)
solve ();
return 0;
}
给个周边吧······
全部评论 1
顶!
2025-04-08 来自 北京
0
有帮助,赞一个