CF1586D. Omkar and the Meaning of Life 题解 纪念一下第一道AC的交互题
题目链接:https://codeforces.com/contest/1586/problem/D
题目大意:
有一个 的排列 ,你最多询问 轮,每轮你可以输入一个长度为 的数列 ,要求 (但 不需要是一个 的排列)。
对于你每次输入的数列 ,程序会产生一个数列 ,其中 ,然后程序会返回给你一个出现过至少两次的 对应的最小坐标 。若没有这个坐标 则返回 。
要求在不超过 轮求出原始的数列 。
解题思路:
第 轮共两次询问:
- 第一次询问,除了 以外,其他所有 ,设程序返回的整数是 ,则:若 且 ,说明第 个位置上面的数比第 个位置上面的数小 ,则从 指向 一条边();
- 第二次询问,除了 以外,其他所有 ,设程序返回的整数是 ,则:若 且 ,说明第 个位置上面的数比第 个位置上面的数大 ,则从 指向 一条边()。
然后这 轮操作之后会发现 —— 形成了一条链,根据链还原出每个数的位置即可。
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 110;
bool in[maxn];
int n, q1, q2, g[maxn], x;
void ask1(int p) {
printf("?");
for (int i = 1; i <= n; i ++) printf(" %d", (i == p) ? 2 : 1);
puts("");
fflush(stdout);
}
void ask2(int p) {
printf("?");
for (int i = 1; i <= n; i ++) printf(" %d", (i == p) ? 1 : 2);
puts("");
fflush(stdout);
}
int val[maxn];
bool vis[maxn];
int main() {
scanf("%d", &n);
for (int p = 1; p <= n; p ++) {
ask1(p);
scanf("%d", &q1);
if (q1 != 0 && q1 != p) {
g[p] = q1;
}
ask2(p);
scanf("%d", &q2);
if (q2 != 0 && q2 != p) {
g[q2] = p;
}
}
for (int i = 1; i <= n; i ++) {
if (!g[i]) x = i;
}
for (int i = 1; i <= n; i ++) vis[ g[i] ] = true;
for (int i = 1; i <= n; i ++) if (!vis[i]) { x = i; break; }
for (int i = 1; i <= n; i ++) {
val[x] = i;
x = g[x];
}
printf("!");
for (int i = 1; i <= n; i ++) printf(" %d", val[i]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人