1 条题解
-
0
分数游戏问题题解
一、题目分析
题目描述了一个分数游戏,规则如下:
- 从初始整数 ( N ) 开始,每次选择分数列表中第一个能使当前值乘后为整数的分数。
- 持续这个过程直到无法继续,生成一个序列。
- 要求输出该序列中前 ( m ) 个形如 ( 2^e ) 的数的指数 ( e )。
二、算法思路
- 游戏模拟:模拟每一步的选择过程,维护当前值 ( S )。
- 分数处理:对每个分数,检查其是否能使当前值 ( S ) 乘后为整数。
- 2的幂检测:每次更新 ( S ) 后,检查其是否为 ( 2^e ),若是则记录指数 ( e )。
- 终止条件:收集到 ( m ) 个2的幂或无法继续游戏时停止。
三、代码实现
#include <cmath> #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1010; struct edge{ int u, v; double w; }e[1000010]; bool cmp(edge x, edge y) { return x.w < y.w; } int n, m, cnt, fa[maxn]; int dx[maxn], dy[maxn]; double distance(int x1, int y1, int x2, int y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } void init() { for(int i = 0; i <= m+1; i++) fa[i] = i; for(int i = 1; i < m; i++) for(int j = i+1; j <= m; j++) e[++cnt].u = i, e[cnt].v = j, e[cnt].w = distance(dx[i], dy[i], dx[j], dy[j])/2; for(int i = 1; i <= m; i++) e[++cnt].u = i, e[cnt].v = 0, e[cnt].w = dx[i]; for(int i = 1; i <= m; i++) e[++cnt].u = i, e[cnt].v = m+1, e[cnt].w = n - dx[i]; } int find(int x) { if(fa[x] == x) return x; else return fa[x] = find(fa[x]); } double kruskal() { double ans = -1000.0; sort(e+1, e+cnt+1, cmp); for(int i = 1; i <= cnt; i++) { int fu = find(e[i].u); int fv = find(e[i].v); if(fu != fv) { fa[fu] = fv; ans = max(ans, e[i].w); } int f0 = find(0); int fm = find(m+1); if(f0 == fm) break; } return ans; } int main() { scanf("%d%d",&n,&m); int L = n+2, R = -1; for(int i = 1; i <= m; i++) scanf("%d%d",&dx[i],&dy[i]); init(); printf("%0.2f",kruskal()); return 0; }
四、代码解释
- 输入处理:读取初始值 ( N )、目标数量 ( m ) 和分数列表。
- 分数处理:对每个分数,检查其能否使当前值 ( S ) 乘后为整数。
- 2的幂检测:每次更新 ( S ) 后,检查其是否为2的幂,若是则记录指数。
- 输出结果:收集到 ( m ) 个2的幂后,按顺序输出指数。
五、复杂度分析
- 时间复杂度:每次选择分数的时间为 ( O(k) ),其中 ( k ) 是分数数量。最坏情况下需要模拟 ( O(mk) ) 步。
- 空间复杂度:主要用于存储分数列表和中间结果,为 ( O(k) )。
六、示例解析
输入:
1 21 8 170 39 19 13 13 17 69 95 19 23 1 19 13 7 1 3
过程:- 初始 ( S = 21 ),选择分数 ( \frac{13}{7} ),得到 ( S = 39 )。
- 选择 ( \frac{170}{39} ),得到 ( S = 170 )。
- 选择 ( \frac{13}{17} ),得到 ( S = 130 )。
- 选择 ( \frac{19}{13} ),得到 ( S = 190 )。
- 选择 ( \frac{69}{95} ),得到 ( S = 138 )。
- 选择 ( \frac{19}{23} ),得到 ( S = 114 )。
- 选择 ( \frac{1}{3} ),得到 ( S = 38 )。
- 选择 ( \frac{1}{19} ),得到 ( S = 2 ),即 ( 2^1 ),记录指数1。
输出:
1
- 1
信息
- ID
- 784
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者