mobile wallpaper 1
1116 字
3 分钟
2026年青鸟工作室招新-机试
2026-03-27

预测难度#

  • Easy : C I K L
  • Easy-medium : D E F J M
  • Medium : G H
  • Medium-hard : B
  • Hard : A

实际情况#

  • Easy : C
  • Easy-medium : I L
  • Medium : K M
  • Medium-hard : G H J
  • Hard : A B D E F

题解#

A - Come A Little Closer#

题意#

移动一个坐标,使能把所有坐标框起来的最小矩形面积最小。

思路#

很明显,面积只与横纵轴方向上最远的 44 个点有关。所以对每个点进行移动,维护答案最小值即可。

核心代码#

struct pt
{
int x, y;
};
struct axis
{
int mn1, mn2, mx2, mx1;
axis(int a, int b)
{
mx1 = mn1 = a;
mx2 = mn2 = b;
update_max();
update_min();
}
void update_min()
{
if(mn1 > mn2)
swap(mn1, mn2);
}
void update_max()
{
if(mx2 > mx1)
swap(mx2, mx1);
}
void add(int n)
{
mx2 = max(mx2, n);
mn2 = min(mn2, n);
update_max();
update_min();
}
int seg(int n)
{
int mx = mx1, mn = mn1;
if(n == mx) mx = mx2;
if(n == mn) mn = mn2;
return mx - mn + 1;
}
};
void solve()
{
int n;
cin >> n;
vector<pt> a(n);
for(auto& [x, y] : a)
cin >> x >> y;
if(n < 3)
{
cout << n << endl;
return;
}
axis xs(a[0].x, a[1].x), ys(a[0].y, a[1].y);
for(int i = 2; i < n; i++)
{
xs.add(a[i].x);
ys.add(a[i].y);
}
int ans = xs.seg(-1) * ys.seg(-1);
for(int i = 0; i < n; i++)
{
int xseg = xs.seg(a[i].x), yseg = ys.seg(a[i].y);
if(xseg * yseg == n - 1)
ans = min(ans, min((xseg + 1) * yseg, xseg * (yseg + 1)));
else ans = min(ans, xseg * yseg);
}
cout << ans << endl;
}

B - Only One Step#

题意#

给出一个出发点 ss,以及范围 [l,r][l, r]。判断范围内有所少个点是可达的。

思路#

不难得出,所有的正整数同属一个连通分量。因此,对于任意起点 ss 和区间 [l,r][l,r],区间内的所有节点均可达,答案即为 rl+1r−l+1

证明

考虑恒等式

f(n)f(n1)=n(n+1)(n1)n=(n21)n2f(n) \cdot f(n-1) = n(n+1) \cdot (n-1)n = (n^2 - 1) \cdot n^2

f(n)f(n1)=f(n21)f(n) \cdot f(n-1) = f(n^2 - 1)

因此,对于任意 n2n \ge 2,节点 n21n^2 - 1 与节点 nnn1n−1 相连。

由此可得:

  • 节点 1122 通过节点 33 相连;

  • 对于任意 k2k \ge 2,节点 kkk1k−1 通过节点 k21k^2−1 相连。

于是,所有正整数通过相邻整数的连接构成一个连通图。

核心代码#

void solve()
{
int s, l, r;
cin >> s >> l >> r;
cout << r - l + 1 << endl;
}

C - Hello BlueBird#

题意#

输出 nn 行带双引号的字符串。

思路#

考察基本语法,注意逃逸字符。

核心代码#

void solve()
{
int n;
cin >> n;
while(n--)
cout << "\"Hello, BlueBird!\"" << endl;
}

D - 正弦函数的前n项泰勒展开#

题意#

按照以下公式算近似值:

sin(x)=n=0(1)n(2n+1)!x2n+1=xx33!+x55!x77!+\sin(x) = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n+1)!} x^{2n+1} = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + \cdots

思路#

每次都从头开始算每一项未必太麻烦了。

从第二项开始,每一项都可以由前一项递推得出:

  • term0=xterm_0 = x

  • termi+1=termi×x2(2i+2)(2i+3)term_{i+1} = -term_i \times \frac{x^2}{(2i+2)(2i+3)}

核心代码#

void solve()
{
double x;
int n;
cin >> x >> n;
double sum = 0.0, term = x;
for(int i = 0; i < n; i++)
{
sum += term;
term = -term * x * x / ((2 * i + 2) * (2 * i + 3));
}
cout << sum << endl;
}

E - What The Dog Doing?(Easy Version)#

题意#

统计所有二进制位的出现频率,问多少个位满足第 ii 位出现频率等于 iii0(i \ge 0)

思路#

很明显,所有的正整数都是可以写成二进制的形式的。那么就可以按照二进制逐位分解,而这个过程就是按照 22 的幂分解的。所以,所有的正整数都满足“刀盾数”的定义。

数据范围是 1ai1091 \leq a_i \leq 10^9,在 intint 类型范围之内。

那么,我们对每个数,跑 3232 位逐位统计频率,然后再遍历 113232 统计答案就好了。

核心代码#

void solve()
{
int n;
cin >> n;
vector<int> a(n);
for(int& i : a)
cin >> i;
vector<int> f(32);
for(int& i : a)
{
int d = 0;
while(i)
{
f[d++] += i & 1;
i >>= 1;
}
}
int ans = 0;
for(int i = 1; i < 32; i++)
if(f[i] == i)
ans++;
cout << ans << endl;
}

F - What The Dog Doing?(Hard Version)#

题意#

再添加任意一个正整数,使最终满足条件的数量尽可能更多。

思路#

换句话来说,对于每一位,都有机会让其频率增加 11

那么如果某一位刚好还差 11,那么我们就可以加上。每个满足该条件的位都会让答案在原基础上 +1+1

那么我们只需要把 EE 题的 if(f[i] == i) 改成 if(f[i] == i || f[i] + 1 == i) 即可通过该题。

核心代码#

void solve()
{
int n;
cin >> n;
vector<int> a(n);
for(int& i : a)
cin >> i;
vector<int> f(32);
for(int& i : a)
{
int d = 0;
while(i)
{
f[d++] += i & 1;
i >>= 1;
}
}
int ans = 0;
for(int i = 1; i < 32; i++)
if(f[i] == i || f[i] + 1 == i)
ans++;
cout << ans << endl;
}

G - 图灵的诅咒#

题意#

不断对数组进行赋值操作:

每一轮对每个元素执行 ai=max(aimex(a),0)a_i = max(a_i - mex(a), 0)

直到整个数组只剩下一种元素。

问操作会持续多少轮。

思路#

经过观察,对数组进行排序之后,每个缺失的数字都会使操作多进行一轮。

核心代码#

Solution 1

void solve()
{
int n;
cin >> n;
vector<int> a(n);
for(int& i : a)
cin >> i;
sort(a.begin(), a.end());
if(a[0] == a[n - 1])
cout << 0 << endl;
else if (a[0] != 0)
cout << -1 << endl;
else
{
int ans = 1;
for(int i = 1; i < n; i++)
ans += max(a[i] - a[i - 1] - 1, 0LL);
cout << ans << endl;
}
}

Solution 2

void solve()
{
int n;
cin >> n;
vector<int> a(n);
for(int& i : a)
cin >> i;
set<int> s(a.begin(), a.end());
if(s.size() == 1)
cout << 0 << endl;
else if(!s.count(0))
cout << -1 << endl;
else cout << *s.rbegin() + 2 - s.size() << endl;
}

H - 这题有教育意义#

题意#

字符串转柱状图。

思路#

按题意模拟即可。

核心代码#

void solve()
{
int n;
string s;
cin >> n >> s;
vector<int> f('Z' + 1);
int mx = 0;
for(char& c : s)
{
f[c]++;
mx = max(mx, f[c]);
}
for(int i = mx; i > 0; i--)
{
for(char c = 'A'; c <= 'Z'; c++)
if(f[c]) cout << (f[c] >= i ? '*' : ' ');
cout << endl;
}
for(char c = 'A'; c <= 'Z'; c++)
if(f[c]) cout << c;
cout << endl;
}

I - 听说牌子是可以合成的(#

题意#

求最多能拥有的金牌数。

思路#

模拟即可。

核心代码#

void solve()
{
int Au, Ag, Cu, x, y;
cin >> Au >> Ag >> Cu >> x >> y;
while(Cu >= x || Ag >= y)
{
Ag += Cu / x;
Cu %= x;
Au += Ag / y;
Cu += Ag / y;
Ag %= y;
}
cout << Au << endl;
}

J - MEX × MIN = const?#

题意#

求区间 mex×minmex \times min

思路#

mex 和 min 之中必有一个为 00

所以,正如题目名字所言:MEX×MIN=const=0MEX × MIN = const = 0

核心代码#

void solve()
{
int _, q;
cin >> _ >> q;
while(q--)
cout << 0 << endl;
}

K - Kill And Keep#

题意#

保持每个数位和不变,尽可能删掉更多的数位。

思路#

删掉所有的 00

核心代码#

Solution 1

void solve()
{
int n;
cin >> n;
vector<int> a(n);
for(int i = 0; i < n; i++)
cin >> a[i];
auto f = [](int x) -> int
{
int res = 0;
while(x)
{
int d = x % 10;
if(d) res = res * 10 + d;
x /= 10;
}
return res;
};
for(int i = 0; i < n; i++)
a[i] = f(f(a[i]));
for(int i = 0; i < n; i++)
cout << a[i] << " \n"[i == n - 1];
}

Solution 2

void solve()
{
int n;
cin >> n;
vector<string> a(n);
for(int i = 0; i < n; i++)
cin >> a[i];
for(int i = 0; i < n; i++)
{
string t = "";
for(char& c : a[i])
if(c != '0') t += c;
a[i] = t;
}
for(int i = 0; i < n; i++)
cout << a[i] << " \n"[i == n - 1];
}

L - Reach The MAX(Easy Version)#

题意#

左右传递赋值,求数组最大和。

思路#

容易想到,选最大值,左右扩散至整个数组。答案就是 max×nmax \times n

核心代码#

void solve()
{
int n;
cin >> n;
vector<int> a(n);
for(int i = 0; i < n; i++)
cin >> a[i];
cout << *max_element(a.begin(), a.end()) * n;
}

M - Reach The MAX(Hard Version)#

题意#

选定区间,然后把区间内的数字都变成两个端点中的较大值。

思路#

不难发现,只有首位两个元素无法被操作影响。其他元素都可以通过一系列操作变成数组的最大值。所以答案就是 a1+an+(n2)×maxa_1 + a_n + (n - 2) \times max

核心代码#

void solve()
{
int n;
cin >> n;
vector<int> a(n);
for(int i = 0; i < n; i++)
cin >> a[i];
cout << a[0] + a[n - 1] + (n - 2) * *max_element(a.begin(), a.end()) << endl;
}
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

2026年青鸟工作室招新-机试
https://blog.hycode.qzz.io/posts/2026-bluebird-recruit/post/
作者
Hycode
发布于
2026-03-27
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录