8 条题解
-
2
Ilumina 题解
30 分解法
的部分分。
已知 ,,并且 和 的值已经给定。我们将 代入 中,得到下列式子。
$$c = \left \lfloor \dfrac{\left \lfloor \dfrac{a}{n} \right \rfloor}{m} \right \rfloor $$因为 均为正整数,并且 和 在 和 中均为分母,因此只有当 且 时, 和 才为正整数。
枚举 中的整数 和 $\left[1, \left \lfloor \dfrac{a}{n} \right \rfloor \right]$ 中的整数 ,并判断是否有满足 $\left \lfloor \dfrac{\left \lfloor \dfrac{a}{n} \right \rfloor}{m} \right \rfloor = c$ 的 和 即可。
60 分解法
的部分分。
使用 表示 的小数部分,显然 ,因此下列式子中 的值不可能改变式子的取值。
$$\left \lfloor \dfrac{a}{nm} \right \rfloor = \left \lfloor \dfrac{\dfrac{a}{n}}{m} \right \rfloor = \left \lfloor \dfrac{\left \lfloor \dfrac{a}{n} \right \rfloor + \left \{ \dfrac{a}{n} \right \} }{m} \right \rfloor = \left \lfloor \dfrac{\left \lfloor \dfrac{a}{n} \right \rfloor}{m} \right \rfloor $$所以 。因为 和 可以为任意正整数,我们令 ,此时 ,。枚举 即可。
80 分解法
和特殊性质的部分分。
对于特殊性质,因为合法的 始终存在,可以发现有如下等式成立。
$$c = \left \lfloor \dfrac{\left \lfloor \dfrac{a}{n} \right \rfloor}{m} \right \rfloor = \left \lfloor \dfrac{b}{m} \right \rfloor $$可以为任意正整数,因此我们令 ,即可得到 。直接输出 的值即可。
正解
由 60 分解法可以发现,问题转化成了判断是否存在正整数 使得 。
如果存在这样的 ,由于构造中 ,直接输出 即可。
$$\left \lfloor \dfrac{a}{\left \lfloor \dfrac{a}{c} \right \rfloor} \right \rfloor \ge \left \lfloor \dfrac{a}{\dfrac{a}{c}} \right \rfloor = \left \lfloor c \right \rfloor = c = \left \lfloor \dfrac{a}{m} \right \rfloor $$存在合法的 当且仅当存在区间 满足 且对于 有 。
很显然,最大的满足条件的 (使用 表示)满足 且 ,容易得到 ,计算 的值并且检验 是否等于 即可判断是否存在合法的 。
单组数据时间复杂度 。
#include <iostream> using namespace std; using ll = long long; int t; ll a, c; int main() { cin.tie(nullptr); ios::sync_with_stdio(false); for (cin >> t; t; --t) { cin >> a >> c; if (a < c) cout << "-1\n"; else cout << (a / (a / c) == c ? a : -1) << '\n'; } return 0; }
可能的其他解法
由 60 分解法可以得到 具有单调性,因此可以对 进行二分查找。单组数据时间复杂度 。
-
1
解题思路:
分类讨论题,分类如下:
- 当 时,由于 为正整数,所以无法得到合法的 。
- 当 时,由于 无法通过连除得到 ,同样无法得到合法的 。
- 其他情况,最简单的方法就是把 设为一,得 。
CODE:
#include <iostream> using namespace std; long long t, a, c; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> t; while (t--) { cin >> a >> c; if (a < c) { cout << "-1\n"; continue; } if (a / (a / c) != c) cout << "-1\n"; else cout << c << '\n'; } return 0; }
Code
-
0
题解分析
问题描述
给定五个正整数 , , , , ,其中 且 。已知 和 的值,求出一个合法的 的值,或者报告不存在合法的 的值。
解题思路
根据题目描述,我们有以下两个等式:
由第一个等式,我们可以推断出 。由第二个等式,我们可以推断出 。结合这两个不等式,我们可以得出 应该满足 。
解决方案
我们可以直接检查 是否满足条件。如果 满足 ,那么 就是一个合法的 值。否则,不存在合法的 值。
代码实现
以下是使用 C++ 实现的代码片段:
#include <iostream> using namespace std; int main() { int t; cin >> t; while(t--) { long long a, c; cin >> a >> c; if(a <= c && a / (a / c) == c) cout << c << endl; else cout << -1 << endl; } return 0; }
时间复杂度分析:
这个解决方案的时间复杂度是 ,因为它只需要常数时间来处理每个测试用例。这使得它非常适合处理大量的测试数据。
-
0
看似很难,实则是一道水题。由 $b=\left\lfloor \frac{a}{n} \right\rfloor , c=\left\lfloor \frac{b}{m} \right\rfloor$,得$ c=\left\lfloor \frac{\left\lfloor \frac{a}{n} \right\rfloor}{m} \right\rfloor=\left\lfloor \frac{a}{nm} \right\rfloor$,
所以 。
再考虑其他无解:
如果 $\left\lfloor \frac{a}{\left\lfloor \frac{a}{c} \right\rfloor} \right\rfloor\gt c$,则找不到 。
证明:略
接下来考虑如何求解。
最简单的解是 。(当 时, 可以 )
故代码如下:
#include<bits/stdc++.h> using namespace std; //a/n/m=c signed main(){ long long t,a,b,c; scanf("%lld",&t); while(t--){ scanf("%lld%lld",&a,&c); if(a/c<1||a/(a/c)<=c)printf("-1\n"); else printf("%lld\n",c); } }
-
-2
这是一道简单题。
我们不妨设 ,因为这样可以让 尽量大,从而找出一个合法的解。
那么问题转换为:是否存在一个 满足 。
我们可以采用二分查找的方法,在 $(\lfloor \frac{a}{c + 1} \rfloor, \lfloor \frac{a}{c} \rfloor]$ 这个区间进行查找即可。
单次询问时间复杂度 。
参考代码如下:
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native") #define _CRT_SECURE_NO_WARNINGS #include <bits/stdc++.h> #define ll long long #define writes(x) write(x), putchar(' ') #define writeln(x) write(x), putchar('\n'); static char buf[100000], * pa(buf), * pb(buf); int st[114], top; #define gc pa == pb && (pb = (pa = buf) + fread(buf, 1, 100000, stdin), pa == pb) ? EOF : *pa++ using namespace std; mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); void debug(auto st, auto ed, bool endline) { for (auto it = st; it != ed; ++it) { cout << *it << " "; } if (endline) cout << '\n'; } template <typename T> void read(T& x) { T t = 0, sgn = 1; char ch = gc; while (!isdigit(ch)) { if (ch == '-') sgn = -sgn; ch = gc; } while (isdigit(ch)) { t = (t << 3) + (t << 1) + (ch ^ 48); ch = gc; } x = sgn * t; } template <typename T, typename ...Args> void read(T& tmp, Args &...tmps) { read(tmp); read(tmps...); } template <typename T> void write(T x) { if (x < 0) putchar('-'), x = -x; top = 0; while (x) { st[++top] = x % 10; x /= 10; } do { putchar(st[top--] + '0'); } while (top > 0); } template <typename T, typename ...Args> void write(T& tmp, Args &...tmps) { writes(tmp); writes(tmps...); } template <typename T> T rand(T l, T r) { return rnd() % (r - l + 1) + l; } int main() { // cin.tie(0)->sync_with_stdio(0); // cout.tie(0)->sync_with_stdio(0); int t; cin >> t; while (t--) { ll a, c; read(a, c); ll l = a / (c + 1) + 1, r = a / c; bool ok = 0; while (l <= r) { ll mid = l + r >> 1; if (a / mid == c) { ok = 1; writeln(a); break; } if (a / mid > c) { l = mid + 1; } else r = mid - 1; } if (!ok) puts("-1"); } }
- 1
信息
- ID
- 14
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 2
- 标签
- 递交数
- 786
- 已通过
- 208
- 上传者