AtCoder Regular Contest 154 D. A + B > C ?(交互 思维+排序)

题目

交互题,

每次给定一个数n(1<=n<=2e3),表明此时有一个长为n的排列p,

你可以最多询问25000次,每次询问,

输出三个允许重复的数i,j,k(1<=i,j,k<=n),

交互机会告诉你pi+pj>pk是否成立,成立返回Yes,否则返回No

所有询问后,你需要输出排列p

思路来源

灵茶群

题解

n<=2e3,q<=25000次,观察着比较像O(nlogn),

实际也是如此,做法就是nlogn+n的

1. 先通过n次询问找到1的位置,即遍历一遍,维护最小值,

询问2*pi>pmn是否成立,其中pmn是当前维护的最小值的下标

若不成立说明2*pi<=pmn,找到了一个新的最小值pmn

1出现的时候,pmn会被替代为1的位置,且后续不会再改变,所以一遍遍历可行

2. 根据1+pj>pk是否成立,来判断j和k的相对位置,

由于pj≠pk,所以若1+pj>pk成立说明pj>pk,否则pj<pk

作为sort函数的排序规则cmp函数即可,

sort函数,可能会因为随机轴的选取,量级虽然是O(nlogn),

但是常数上,实际次数会略微超限

所以,这里采用stable_sort函数,内部归并排序,稳定nlogn次

(感觉好像之前做过类似的排序)

代码

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int N=2e3+10;
int n,mn=1,rk[N],a[N];
string s;
bool ask(int i,int j,int k){
    cout<<"? "<<i<<" "<<j<<" "<<k<<endl;
    cin>>s;
    return s[0]=='Y';
}
int main(){
    cin>>n;
    for(int i=1;i<=n;++i){
        //2*pi<=mn,mn=pi
        rk[i]=i;
        if(!ask(i,i,mn)){
            mn=i;
        }
    }
    stable_sort(rk+1,rk+n+1,[&](int x,int y){
        return !ask(mn,x,y);
    });
    for(int i=1;i<=n;++i){
        a[rk[i]]=i;
    }
    cout<<"!";
    for(int i=1;i<=n;++i){
        cout<<" "<<a[i];
    }
    cout<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Code92007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值