11 条题解
-
1
J1A. 『FLA - III』Spectral
思路
模拟。当火焰的温度相同时,跳出循环并输出答案。
Code
#include <bits/stdc++.h> using namespace std; int T, n; double k, t, p; int main() { scanf("%d", &T); while (T -- ) { t = 0; scanf("%d %lf", &n, &k); for (int i = 1; i <= n; i ++ ) { p = t; t = max(t, k + t / i); if (p == t) i = n; } printf("%.1lf\n", t); } return 0; }
-
-1
题解
思路
这题只需根据题目递推关系式,找规律即可
解题方法
我们从 开始计算
$T_5=k+T_4/5=3/40 \times k=(3/(2 \times 4 \times 5))\times k$
$T_6=k+T_5/6=3/240 \times k=(3/(2 \times 4 \times 5 \times 6))\times k$
我们设
众所周知,随着 的变化, 越来越大,也就是除数越来越大.
而被除数不变,除数变大,商也就越来越小,即 越来越小 .
可以看出,除 到 不变,其余 的趋势为越来越小.
又因为 ,即
所以,当 时,只能取 或 .
因为 , ,
所以
所以取 , 即 .
否则,即 时.
因为除 到 不变,其余 的趋势为越来越小.
所以 时,答案取 或 时最大,即 .
时间复杂度:
添加时间复杂度, 示例:
空间复杂度:
添加空间复杂度, 示例:
Code
#include <bits/stdc++.h> using namespace std; int main() { int t; cin>>t; while(t--) { int n; cin>>n; double k; cin>>k; double ans=k*3/2*1.00; //保留精度 if(n!=1) printf("%.1lf\n",ans); else printf("%.1lf\n",k); //特殊情况 } return 0; }
-
-2
赛时用实时更新最大值并判断的方法通过了此题,现在证明一下这个算法的时间复杂度。
首先,我们可以将 都表示为 的形式, 显然是 , 通过推导可得 。随着 的增加, 也随之增加,那么 也会变得越来越小。对于 在 中的 ,我们就有 ,实际上从 开始就已经满足严格单调递减了,所以这个算法最多会执行 次,时间复杂度显然是 。
参考代码如下:
// #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 n, k; cin >> n >> k; double ans = 0.0; double mxn = 0.0; for (int i = 1; i <= n; i++) { ans = (1.0 * k + 1.0 * ans / i); if (ans > mxn) { mxn = ans; } else break; } cout << fixed << setprecision(1) << mxn << '\n'; } }
-
-2
模拟、数学
测试点
容易得到在 时答案为 ,在 时答案为 。
测试点
暴力计算 后取最大值。
测试点
序列 的最大值是 和 ,读者可以自行查看题解结尾处的证明。
当 时答案为 ,否则答案为 。
单组数据时间复杂度 。
#include<bits/stdc++.h> using namespace std; int T,n,k; int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&k); if(n==1) printf("%d.0\n",k); else if(k%2==0) printf("%d.0\n",k+k/2); else printf("%d.5\n",k+k/2); } return 0; }
证明:若 ,由于 ,,那么 $T_{i+2}-T_{i+1}=\dfrac{T_{i+1}}{i+2}- \dfrac{T_i}{i+1}<0$,因为 的分母更大,分子更小。
因为 ,所以 ,又因为 所以 。以此类推,只要存在 ,那么对于所有大于 的整数 都有 ,又因为 ,所以序列 的最大值只可能在 中取到,可知序列 的最大值为 。
-
-3
J1A 题解
思路
通过找规律,发现:
- 当 时,答案为 ;
- 当 时,答案为 ;
- 当 时,答案为 。
复杂度
时间复杂度:
空间复杂度:
Code
#include <bits/stdc++.h> int main() { int _t; std::cin >> _t; for(; _t; --_t) { long double n, k; std::cin >> n >> k; long double ans; if(n == 0) ans = 0; else if(n == 1) ans = k; else ans = 1.5 * k; std::cout << std::fixed << std::setprecision(1) << ans << '\n'; } }
-
-3
J1A题解
40分思路
暴力解决
复杂度
时间复杂度: ,空间复杂度:
Code
#include <bits/stdc++.h> using namespace std; int i, j, k, n, T; double C; int main() { scanf("%d", &T); for (i = 1; i <= T; i++) { scanf("%d %d", &n, &k); for (j = 1; j <= n; j++) C = C / j + k; printf("%.1lf\n", C); } return 0; }
喜提TLE80分思路
还是暴力,只不过加一个最大值
复杂度
时间复杂度: ,空间复杂度:
Code
#include <bits/stdc++.h> using namespace std; int i, j, k, n, T; double C, c; int main() { scanf("%d", &T); for (i = 1; i <= T; i++) { scanf("%d %d", &n, &k); for (j = 1; j <= n; j++) c = C / j + k, C = max(C, c); printf("%.1lf\n", C); } return 0; }
又双叒叕敠敪喜提TLE100分思路
打一个表,发现如下规律:
|||||| |-----|-----|-----|-----|-----| ||||||整个序列 的峰值在 和 。
复杂度
时间复杂度: ,空间复杂度:
Code
#include <bits/stdc++.h> using namespace std; int i, k, n, T; int main() { scanf("%d", &T); for (i = 1; i <= T; i++) { scanf("%d %d", &n, &k); if (n == 1) printf("%d.0\n", k); else if (k & 1) printf("%d.5\n", k + k / 2); else printf("%d.0\n", k + k / 2); } return 0; }
终于AC了 -
-3
由于此题 都很(hen)大,所以易得是奇思妙想题。
打个表 : |烧炭数|| |:---:|:---:| ||| ||| ||| ||| ||| 容易发现, 在烧2块时达到峰值
所以直接算,特判 就行
代码如下:
#include<bits/stdc++.h> using namespace std; double ans,f; signed main(){ int t,n,k; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&k); ans=0;f=0; if(n<2)ans=k; else ans=1.5*k; printf("%.1lf\n",ans); } return 0; }
-
-3
P10781 【MX-J1-T1】『FLA - III』Spectral 题解
大致思路:
这道题目最直接的方法就是暴力找最大值,显然会超时,接着就是进行打表,我们会发现,这道题的函数,是一个单峰函数,只会在一开始持续上升,在一定的位置持续下降,所以我们只需要找到那个转折点,直接退出即可。
代码实现:
#include <bits/stdc++.h> #define int long long using namespace std; const int MOD = 1e9 + 7; const int N = 5e5 + 10; inline int read() { int x = 0, f = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); } while (isdigit(ch)) { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } int T; signed main() { T = read(); while (T--) { double k, res = 0; int n; n = read(); cin >> k; if(n == 1) cout << fixed << setprecision(1) << k << "\n"; else{ for (int i = 1;i <= n; ++ i) { if(k + res / i < res) break; else res = k + res / i; } cout << fixed << setprecision(1) << res << "\n"; } } return 0; }
这样这道题目就完成啦!!!
- 1
信息
- ID
- 13
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 2
- 标签
- 递交数
- 1259
- 已通过
- 336
- 上传者