语法周赛 Round 19 题解
2024年12月25日大约 3 分钟
A. 三位数重新排列
分析
- 难度:简单数位分解,基础条件判断。
- 子任务 1(30 分):显然直接输出
即可。 - 子任务 2(30 分):分别取出来个位、十位、百位,三个数排序后输出即可。
- 子任务 3(40 分):子任务
中的有可能得到0
或者00
开头的数。可以用条件判断特殊处理,也可以直接把三个数字重新组成为一个数。
满分参考代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin >> n;
int a = n / 100;
int b = n / 10 % 10;
int c = n % 10;
if (a > b)
swap(a, b);
if (a > c)
swap(a, c);
if (b > c)
swap(b, c);
cout << a * 100 + b * 10 + c;
return 0;
}
B. 千钱买千鸡
分析
- 难度:枚举优化。
- 子任务 1(30 分):显然不可能买前两种鸡了,暴力枚举后两种各买几只即可。
- 子任务 2(30 分):没啥特殊作用的凑数子任务。
- 子任务 3(40 分):其实就是个百钱买百鸡的升级版。按百钱买百鸡一样的模式,枚举前三种鸡的数量,然后算出第四种鸡的数量,计算是否满足条件即可。看上去
可能会超时,但实际上控制好三种鸡数量之和为 的话,常数是非常小的。而且也可以进一步优化,第四种鸡的数量必然是 的倍数,可以考虑先枚举第四种鸡,当 为 时也可以直接输出0 0 0 1000
满分参考代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
int ans = 0;
for (int i = 0; i <= 1000; i++)
for (int j = 0; j <= 1000 - i; j++)
for (int k = 0; k <= 1000 - i - j; k++)
{
int l = 1000 - i - j - k;
if (d != 0 && l % d == 0 && i * a + j * b + k * c + l / d == 1000)
{
cout << i << " " << j << " " << k << " " << l;
return 0;
}
}
cout << "-i";
return 0;
}
C. 前后洗牌
分析
- 难度:简单字符串枚举
- 子任务 1(30 分):直接输出
即可。 - 子任务 2(30 分):让
枚举前半部分,依次输出 与对称位置即可。 - 子任务 3(40 分):做法很多。考虑在子任务
的基础上中间的位置只输出依次就好。可以用两个变量分别指示头部和尾部。当然也可以真的按照题目意思模拟。
满分参考代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s, t;
cin >> s;
t = "";
int l = 0;
int r = (int)s.size() - 1;
while (l <= r)
{
if (l <= r)
{
t += s[l];
l++;
}
if (l <= r)
{
t += s[r];
r--;
}
}
cout << t;
return 0;
}
D. 一维分形图
分析
- 难度:基础递归/打表。
- 按点得分,数据范围又小。所以可以先把样例给的五个点打表,那
分就得到了。 - 后面的分数可以考虑手动模拟画出来,然后打表,这题是不会超源文件长度限制的。
- 标准做法自然是递归地去画这个分形图。
满分参考代码
#include <bits/stdc++.h>
using namespace std;
int n3[10];
string s;
void f(int k, int pos)
{
if (k == 0)
{
s[pos] = '#';
return;
}
f(k - 1, pos);
f(k - 1, pos + 2 * n3[k - 1]);
}
int main()
{
int n;
cin >> n;
n3[0] = 1;
for (int i = 1; i <= n; i++)
n3[i] = n3[i - 1] * 3;
s.resize(n3[n]);
for (int i = 0; i < s.size(); i++)
s[i] = '.';
f(n, 0);
cout << s;
return 0;
}