【题解】CF2067D Object Identification
CF2067D - Object Identification
题目大意
有一个对你公开的
- A:一个有
个结点的有向图,每一条边从 指向 。 - B:一个二维坐标系中的一些点,每个点的坐标为
。
你可以对这个图进行询问:
- 若这个图是一个有向图,则你的询问
为从结点 到结点 的最短路径长度。 - 若这个图是一个二维坐标系,则你的询问
为从点 到 的曼哈顿距离 。
现在,你有最多
思路
很好的一个交互题,一看题目,居然只给
要区分这两种图,我们要从二者分别的特征入手:
- 有向图:所有的边是单向的,不可反向行走,因此两个结点正着走和反着走的距离不一定相同。
- 二维坐标系:所有的点两两之间的曼哈顿距离是相同的,因此正着走和反着走的距离都相同,并在该题目条件下,不存在重合的两个点,因此距离一定不为
。
因此,这里有一个初步的思路,挑选两个数字,正着问一次,反着问一次,判断两次询问的距离是否相同。
但很遗憾,就算是有向图,正着和反着的距离也有可能会相同(如下图中的
因此,若问出来距离相同,仍然无法判断为有向图还是二维坐标系。
那么,有没有什么更特殊的点,能直接作为判断标志呢?
有的,在有向图(不含自环)中,若一个结点的出度为
也就是说,如果有
当然,不难发现,还有一种情况会发生,那就是
在这种情况中,如果是有向图,则不存在出度为
这里我们就要用到我们
因此,我们可以用这个不等式来区分有向图和二维坐标系,那选用哪两个数字来询问呢?
这里我们选取
如此一番操作后,我们还剩下一次询问机会,并且如果这个时候还没有得出答案,则只剩下一种情况:
再仔细观察可以发现,在有
此时,我们仅剩一条边没有连接,也就是数字
因此这时只需要再询问一次
AC CODE
const int N = 2e5 + 9;
int a[N];
int p[N];
int cnt[N];
int ask(int x, int y) {
cout << "? " << x << ' ' << y << endl;
int op;cin >> op;
return op;
}
void solve()
{
int n;cin >> n;
for(int i = 1;i <= n;i ++)cin >> a[i];
for(int i = 1;i <= n;i ++)cnt[i] = 0;
for(int i = 1;i <= n;i ++)cnt[a[i]] ++, p[a[i]] = i;
for(int i = 1;i <= n;i ++) {
if(!cnt[i]) {
if(ask(i, (i % n + 1)) == 0) {
cout << "! A" << endl;
} else {
cout << "! B" << endl;
}
return;
}
}
int ck = ask(p[1], p[n]);
if(ck >= n) {
cout << "! B" << endl;
return;
}
if(ck < n - 1) {
cout << "! A" << endl;
return;
}
int dk = ask(p[n], p[1]);
if(dk == ck) {
cout << "! B" << endl;
} else {
cout << "! A" << endl;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库