1 条题解
-
0
自动搬运
来自洛谷,原作者为

Cutest_Junior
平平淡淡才是真搬运于
2025-08-24 22:28:50,当前版本为作者最后更新于2021-02-10 21:49:50,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题解 P7329 【[w33z-2018] Dream and More Discs】
题意
- 阴间交互题;
- 有 类音乐盘,每类有 片按重要度递增排序的音乐盘,所有盘重要度互不相同;
- 每次可以询问第 类第 个盘的重要度,求所有盘中重要度第 小的是哪个盘;
- ,,询问次数不超过 次,重要度都是不超过 的正整数。
做法
记 为第 类第 个盘的重要度。
对每个区间二分,若当前 ,就可以找到 满足 ,把 改为 ,也就是说,原来从 到 的这段区间的盘都不用考虑了。
想一想,为什么。根据上面的定义,比 小的至少有 (不包括它本身,所以要减一)个盘,而 ,说明第 个盘的重要度一定小于 。
同理,若当前 ,则可以找到 满足 ,把 改为 。
可以发现每一类最多查询 次,总查询次数 。
十年 OI 一场空,不开 long long 见祖宗。
我才不会告诉你我因为没开 long long 连 WA 12 次。代码
#include <cstdio> using namespace std; typedef long long ll; const int N = 55; int l[N], r[N], mid[N]; ll ans[N]; void in(int x, int y) { printf("? %d %d\n", x, y); fflush(stdout); scanf("%lld", &ans[x]); } int main() { int n, m, k, th; scanf("%d%d%d%d", &n, &m, &k, &th); for (int i = 1; i <= n; ++i) { l[i] = 1, r[i] = (1 << m) - 1; mid[i] = (l[i] + r[i]) >> 1; in(i, mid[i]); } // printf("%d %d\n", mid[1], mid[2]); for (int i = 1; i <= n * m; ++i) { int minn = 1, maxx = 1; int cnt = mid[1]; for (int j = 2; j <= n; ++j) { cnt += mid[j]; if (l[j] > r[j]) { continue; } if (l[minn] > r[minn]) { minn = j; } if (l[maxx] > r[maxx]) { maxx = j; } if (ans[j] < ans[minn]) { minn = j; } if (ans[j] > ans[maxx]) { maxx = j; } } // printf("cnt %d\n", cnt); if (k < cnt) { r[maxx] = mid[maxx] - 1; mid[maxx] = (l[maxx] + r[maxx]) >> 1; if (l[maxx] <= r[maxx]) { in(maxx, mid[maxx]); } } else { l[minn] = mid[minn] + 1; mid[minn] = (l[minn] + r[minn]) >> 1; if (l[minn] <= r[minn]) { in(minn, mid[minn]); } } if (i == n * m) { printf("! %d %d", minn, mid[minn]); return 0; } } }
- 1
信息
- ID
- 6298
- 时间
- 2000ms
- 内存
- 250MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者