AcWing 113. 特殊排序

时间:2023-03-18
本文章向大家介绍AcWing 113. 特殊排序,主要内容包括有关数据、题目大意、提示、解法分析、AC Code、使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

有关数据

\(\texttt{Time Limit}\) \(\texttt{Memory Limit}\) \(\texttt{Difficulty}\)
\(\color{green}{\texttt{1 sec}}\) \(\color{red}{\texttt{64 MB}}\) \(\color{blue}{\texttt{Easy}}\)

题目大意

\(N\) 个元素,编号 \(1,2\cdots,N\),每一对元素之间的大小关系是确定的,关系具有反对称性,但不具有传递性。
注意:不存在两个元素大小相等的情况。
也就是说,元素的大小关系是 \(N\) 个点与 \(\frac{N\times(N−1)}{2}\) 条有向边构成的任意有向图。
然而,这是一道交互式试题,这些关系不能一次性得知,你必须通过不超过 \(10000\) 次提问来获取信息,每次提问只能了解某两个元素之间的关系。
将 ¥N¥ 个元素排好序后,把他们的编号以数组的形式输出,如果答案不唯一,则输出任意一个均可。

提示

  • \(1 \leq N \leq 1000\)

解法分析

这道题我们采用二分。
首先,考虑归纳法。如果已经确定了前 \(k-1\) 个元素的大小关系,那么对于第 \(k\) 个数,我们可以尝试二分。
因为前 \(k-1\) 个数是单调递增的,所以二分前 \(k-1\) 个数。如果小于,往上区间走;否则,往下区间走。这样,总的询问次数是 \(n\log{n}\),题目可以接受。
至此,我们做出了这一题。
至于为什么二分一定能搜到……?这需要说吗?

AC Code

# include <bits/stdc++.h>
using namespace std;

# define ll long long
# define lf double
# define GO(i,a,b) for(ll i = a; i <= b; i ++)
# define RO(i,b,a) for(ll i = b; i >= a; i --)
# define FO(i,u,head,e) for(int i = head[u]; i; i = e[i].next)
# define CI const int
# define pii pair<int,int>
# define MP(a,b) make_pair(a, b)
# define PB push_back
# define mem(a,x) memset(a, x, sizeof a)
# define F first
# define S second

// Forward declaration of compare API.
// bool compare(int a, int b);
// return bool means whether a is less than b.

class Solution {
public:
    vector<int> specialSort(int n) {
    	vector <int> ans;
    	ans.PB(1);
		GO (i, 2, n){
    		int l = 1, r = i - 1;
    		int pos = 0;
    		while (l <= r){
    			int mid = (l + r) >> 1;
    			bool res = compare(ans[mid - 1], i);
    			if (res){
    				pos = mid;
    				l = mid + 1;
				}
				else r = mid - 1;
			}
			ans.insert(ans.begin() + pos, i);
		}
		return ans;
    }
};

原文地址:https://www.cnblogs.com/yh2021shx/p/Special_Sort.html