1 条题解
-
0
【2022年省赛B组】试题J: 砍竹子
题解
每次使用魔法砍竹子,可以使得柱子高度变成$\Bigg \lfloor \sqrt{\big \lfloor\dfrac{H}{2} \big \rfloor + 1}\Bigg \rfloor$。可以发现,砍竹子的次数在log级别以下。
当高度达到上限时,最多只需要砍6次,高度即可变为1。 那么对于每棵竹子,可以暴力求出每次砍完之后的高度。表示第棵竹子,倒数第次砍之后的高度。 那么我们最开始可以求出所有的竹子单独使用魔法的次数,并且同时记录数组,即每棵树每次砍完后的高度。 对于相邻的低和第棵竹子,如果存在高度相同,则可以一并砍掉,此时将减1即可。 遍历所有和,存在相同高度则答案减1,最终则是所有竹子变成1的最少魔法使用次数。
提交代码
#include<bits/stdc++.h> typedef long long LL; const int N = 2e5 + 10; std::vector<LL> dp[N]; void solve() { int ans = 0; int n; std::cin >> n; for(int i = 0; i < n; i++) { long double h; std::cin >> h; while(h > 1) { dp[i].push_back(h); h = std::floor(std::sqrt(std::floor(0.5 * h) + 1)); ans++; } std::sort(dp[i].begin(), dp[i].end()); } for(int len = 0; len < 6; len++) { for(int i = n - 1; i > 0; i--) { if(dp[i].size() > len && dp[i - 1].size() > len && dp[i][len] == dp[i - 1][len]) { ans--; } } } std::cout << ans << "\n"; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); int t = 1; while(t--) solve(); return 0; }
- 1
信息
- ID
- 975
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 25
- 已通过
- 5
- 上传者