AcWing 113交互特殊排序——二分

Posted ty02

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 113交互特殊排序——二分相关的知识,希望对你有一定的参考价值。

(题面来自AcWing)

有N个元素,编号1.2..N,每一对元素之间的大小关系是确定的,关系不具有传递性。

也就是说,元素的大小关系是N个点与N*(N-1)/2条有向边构成的任意有向图。

然而,这是一道交互式试题,这些关系不能一次性得知,你必须通过不超过10000次提问来获取信息,每次提问只能了解某两个元素之间的关系。

现在请你把这N个元素排成一行,使得每个元素都小于右边与它相邻的元素。

你可以通过我们预设的bool函数compare来获得两个元素之间的大小关系。

例如,编号为a和b的两个元素,如果元素a小于元素b,则compare(a,b)返回true,否则返回false。

将N个元素排好序后,把他们的编号以数组的形式输出,如果答案不唯一,则输出任意一个均可。

数据范围

1N1000

 

  遇到的第一道交互题。看到N的范围考虑插入排序:我们每次在原序列中找出合适的位置,把新的数字插入。题中要求询问小于等于10000次,大约是NogN的范围,那么就来二分了。

  二分时每次check一下数组中当前元素ans[mid]与i的关系;如果i < ans[mid],则说明mid的左边一定存在一个位置k满足ans[k] > i && ans[k - 1] < i,否则左边的数都大于i,插入到第一个位置即可。同理,i > ans[mid]就往右边插入。因为是向下取整二分,最终得到的ans[l]是大于i的第一个数。注意特判ans[l]也小于i的边界。

代码:

  1. // Forward declaration of compare API.  
  2. // bool compare(int a, int b);  
  3. // return bool means whether a is less than b.  
  4.   
  5. class Solution   
  6. public:  
  7.     vector<int> specialSort(int N)   
  8.         vector<int> ans;  
  9.         ans.push_back(1);  
  10.         for (int i = 2; i <= N; ++i)   
  11.             int l = 0, r = ans.size() - 1;  
  12.             while (l < r)   
  13.                 int mid = l + r >> 1;  
  14.                 if (compare(i, ans[mid]))  
  15.                     r = mid;  
  16.                 else l = mid + 1;  
  17.               
  18.             ans.push_back(i);  
  19.             if (compare(ans[l], i)) continue;  
  20.             for (int j = ans.size() - 2; j >= l; --j)  
  21.                 swap(ans[j], ans[j + 1]);  
  22.           
  23.         return ans;  
  24.       
  25. ;  

 

以上是关于AcWing 113交互特殊排序——二分的主要内容,如果未能解决你的问题,请参考以下文章

算法刷题AcWing 113. 特殊排序——二分

AcWing基础算法课Level-3 第一讲 基础算法

113. 特殊排序

AcWing算法基础课排序 二分 高精度 前缀和 差分 双指针 位运算 离散化 区间合并

第六章 基础算法

AcWing 1996. 打乱字母(贪心+二分)