Type 题解
Created Dec 13, 2025, 17:00:00 / Updated Dec 13, 2025, 17:00:00
Views — / Comments — / Words 404
牛客小白月赛125题解
这场比赛是数学场吧。一场下来,没几个题是没有数学公式的。而且没有考的算法。都是最基本的,看的就是基本盘坚不坚定。 这道题就是给一个式子求解$a^b = x$求$a$, $b$的大小,我们一眼就可以看出当$b = 1$时 $a = x$,得出答案,因为$x^1=x$ 题目大意呢就是求$\leq x$的数至少有$k$...
这场比赛是数学场吧。一场下来,没几个题是没有数学公式的。而且没有考的算法。都是最基本的,看的就是基本盘坚不坚定。
这道题就是给一个式子求解求, 的大小,我们一眼就可以看出当时 ,得出答案,因为
void solve() {
read(x);
cout << x << ' ' << 1 << endl;
}
题目大意呢就是求的数至少有个直接用二分写了
void solve() {
int q;
read(n, q);
for (int i = 0; i < n; i++)
read(w[i]);
sort(w, w + n);
while (q --) {
read(k, x);
int rank = lower_bound(w, w + n, x) - w;
puts(rank >= k ? "Yes" : "No");
}
}
给一个数学式子,将数组中,变成,让最大,我们可以贪心的思考如何让最大呢。根据即当时,式子成立。我们让, 尽可能的近。从小开始遍历就行了。用优先队列写。让,的尽可能的差值小
void solve() {
read(n);
priority_queue<double, vector<double>, greater<>> pq;
for (int i = 0; i < n; i++)
read(w[i]), pq.push(w[i]);
while (pq.size() != 1) {
double x = pq.top();
pq.pop();
double y = pq.top();
pq.pop();
double res = sqrt(x * y);
pq.push(res);
}
printf("%.12lf", pq.top());
}
这道题,我是半蒙半写,写出来的。我怕爆long long,用的python暴力写的题。没什么含金量。赛后看看题解是什么。
我先说说是如何暴力的。我们可以知道有两种操作:
第二种操作就是第一种操作多次使用。假设这个数是
------
x + 9 * n = 999...999
------
(x + 9 * n) * 9 + m * 9 = 999...999
这两种操作展开看
------
n = (999...999 - x) / 9 # 答案是n
------
9 * n + m = 111...111 # 答案是n + 1 + m +1是*9这个操作
我们只需要构造然后暴力的看看上面哪一个的答案小就行。这就是我的暴力题解
def solve():
global arr
x = ii()
ln = len(str(x))
while True:
base = 10 ** ln - 1
ans = inf
if x == base:
print(0)
return
base -= x
if base % 9 == 0:
ans = base // 9
base += x
if base % 9 == 0:
base //= 9
base -= x
if base >= 0:
m = base // 9
n = base % 9
ans = fmin(ans, m + n + 1)
if ans != inf:
print(ans)
return
ln += 1
这道题是构造题。我场上思考了好长时间。构造有三个限制
我们可以知道对于的无解。
我发现这个规律(其实就是打表):
arr: 2 3 4 5 .... n 1
i: 1 2 3 4 .... n - 1 n
arr + i: 3 5 7 9 .... 2n - 1 n + 1
对于是奇数的时候成立,是偶数的时候不成立。这是我们就要找如何使偶数时成立
其实我们可以发现是奇数,并且是单调递增的(除了),而是根据的值变化的。
当是偶数时会与前面的一个数重合这时,如果我们将和前面的偶数()换一下位置,这样是偶数,是偶数。并且让就行,这样就构造出来了。我选的是前面的这个数,这样的话。就需要特判一下的时候了。其他就根据前面的构造就行了
void solve() {
read(n);
if (n == 1 || n == 2) {
cout << -1 << endl;
return;
}
if (n == 4) {
cout << 3 << ' ' << 1 << ' ' << 4 << ' ' << 2 << endl;
return;
}
vector<int> p(n);
iota(p.begin(), p.end(), 2);
p[n - 1] = 1;
if (n & 1) {
for (int x: p)
cout << x << ' ';
cout << endl;
return;
}
swap(p[2], p.back());
for (int x: p)
cout << x << ' ';
cout << endl;
}
这道题我写的有点复杂。先看看题目的数学公式吧:
形式化地说,对于给定两个整数区间 和。你需要计算以下式子的结果:
简单来说,计算结果为:对区间每一个整数 ,依次对从 到 内所有整数取模后求和
我想的是分类讨论:
这两种讨论。
我们可以发现
int l, r, p, q;
i64 calc(i64 a, i64 b) {
if (a > b)
return 0;
return (a + b) * (b - a + 1) / 2;
}
i64 bushi(int x, int q) {
if (x < q)
return 0;
x = x - q;
int base = x / q;
int res = x % q;
i64 ans = calc(1, p - 1) * base;
ans += calc(1, min(res, p - 1));
return ans;
}
void solve() {
read(l, r, p, q);
if (p <= l && r <= q)
return cout << 0 << endl, void();
i64 ans = 0;
if (l < p) {
ans += calc(l, min(p - 1, r));
}
if (r > q) {
// q + 1 ~ r -> 0 ~ q - 1
ans += bushi(r, q) - bushi(l - 1, q);
}
cout << ans << endl;
}
Comments
Notes, questions, and follow-ups are welcome here.
Comments are temporarily unavailable because
WALINE_SERVER_URL or PUBLIC_WALINE_SERVER_URLis not configured.