题目链接: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; }