【Educational Codeforces Round 101 (Rated for Div. 2) D】Ceil Divisions
题目链接
翻译
定义一个数组
你每次可以选择两个下标 和 ,让你用 去除 (向上取整)。
希望最后 个数字中剩下 个 以及 个 。
且操作的次数不能超过 次。
题解
思路是这样的,对于 的产生,只需用 去除 即可。
看样子我们只需要进行 就能完成这个任务,但是有一个问题,最大的 没有 让他进行除了。
想法是留一个比较小的数字 ,让 一直去除 。
为 的话,太小了,要除的次数太多了。
所以就一直试这个数字 ,发现 时是合适的。
那么就用 这样的操作把除了 这三个数字之外的数字都变成 。
然后用 不断除 ,因为 就大于 了,所以只需三次操作。
而 变成 则需要除 六次。
再加上 的 以及 的 次。
那么最多的操作次数就为 次操作。
对于 小于等于 的情况,就直接保留 和 ,然后用 除 就行了。
代码
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N = 2e5;
int T, n,tot;
int x[2*N + 10], y[2*N + 10];
void addOpe(int i, int j) {
x[++tot] = i;y[tot] = j;
}
void outAnswer() {
cout << tot << endl;
for (int i = 1; i <= tot; i++) {
cout << x[i] << " " << y[i] << endl;
}
}
int main() {
#ifdef LOCAL_DEFINE
freopen("in.txt", "r", stdin);
#endif // LOCAL_DEFINE
ios::sync_with_stdio(0), cin.tie(0);
cin >> T;
while(T--){
tot = 0;
cin >> n;
if (n <= 64) {
for (int i = 3; i <= n - 1; i++) {
addOpe(i, i + 1);
}
//a[3..n-1]=1
int an = n;
while (an != 1) {
addOpe(n, 2);
an = ceil(1.0 * an / 2.0);
}
}
else {
const int mid = 64;
//n>100
for (int i = 3; i <= mid-1; i++) {
addOpe(i, i + 1);
}
//a[3..mid-1] = 1
for (int i = mid+1; i <= n - 1; i++) {
addOpe(i, i + 1);
}
//a[mid+1..n-1]=1
int an = n;
while (an != 1) {
addOpe(n, mid);
an = ceil(1.0 * an / mid);
}
int amid = mid;
while (amid != 1) {
addOpe(mid, 2);
amid = ceil(1.0 * amid / 2);
}
}
outAnswer();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2019-03-06 【Codeforces 979B】Treasure Hunt
2019-03-06 【Codeforces 582A】GCD Table