题目链接:Problem - 1353D - Codeforceshttps://codeforces.com/problemset/problem/1353/D
题目大意:
往空的数组里从1~n填数字,每次填最长的空区间的中间位置(位置向下取整)。
思路:
用二分判断放每一个数字时此区间的大小。
排序完后再将数字放入对应的位置。
方法:
用dfs去实现二分:
void dfs(ll l ,ll r){//用二分判断填一个数字时的区间大小 if(l <= r){ll mid = l + (r-l >> 1);p[mid].first = l-r-1;//区间大的先排,负数影响了排序规则 dfs(l ,mid-1);dfs(mid+1 ,r);}return; }
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; #define endl "\n"const ll N = 2e5+7; ll n; ll v[N]; pair<ll,ll>p[N];void dfs(ll l ,ll r){//用二分判断填一个数字时的区间大小 if(l <= r){ll mid = l + (r-l >> 1);p[mid].first = l-r-1;//区间大的先排,负数影响了排序规则 dfs(l ,mid-1);dfs(mid+1 ,r);}return; }void solve(){cin >> n;dfs(1,n);for(ll i = 1 ; i <= n ; i ++)//数字放在哪个位置 p[i].second=i;sort(p+1,p+n+1);for(ll i = 1 ; i <= n ; i ++)//依次放数字进数组 v[p[i].second]=i;for(ll i = 1 ; i <= n ; i ++)i > 1 ? cout << " " << v[i] : cout << v[i];cout << endl;return; }int main() {ll t=1;cin >> t;while(t --)solve();return 0; }