Lena Sort 构造题,很多细节的模拟
https://www.hackerrank.com/contests/101hack46/challenges/lena-sort
把题目转换成一颗二叉树,也就是当前的节点是cur,然后大的,放右边,小的,放左边。
然后所有节点的深度总和,就是答案c。现在就是要你构造一颗这样的树。
最大的树就是左偏树,然后从最后一个节点开始模拟,如果它放移上一格,贡献就会 - 1,所以肯定能构造出一颗满意的树。
至于细节比较多,慢慢debug把。代码也非常混乱。
数据
15 18
7 12
主要是理解为什么这样就是答案。
其实每一个节点的贡献,就是路径的长度,路径的长度表示它被比较了多少次。
一直都是和它的祖先比较。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <assert.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; #include <iostream> #include <sstream> #include <vector> #include <set> #include <map> #include <queue> #include <string> #include <bitset> const int maxn = 1e5 + 20; vector<int>G[maxn]; int findmin(int len) { if (len == 1) return 0; if (len == 2) return 1; return (len - 2) * 2; } LL findmax(int len) { return 1LL * len * (len - 1) / 2; } struct node { int cnt, deep; node(int a, int b) : cnt(a), deep(b) {} }; queue<struct node> que; int val; int ans[maxn]; void show(int id) { if (G[id].size() == 0) { ans[id] = val; // cout << val << " "; ++val; return; } show(G[id][0]); ans[id] = val; // cout << val << " "; ++val; if (G[id].size() == 2) { show(G[id][1]); } } int check(vector<int> arr) { if (arr.size() <= 1) return 0; vector<int> les; vector<int> big; for (int i = 1; i < arr.size(); ++i) { if (arr[i] > arr[0]) big.push_back(arr[i]); else les.push_back(arr[i]); } return check(les) + check(big) + arr.size() - 1; } int len, c; void bfs(int cur) { queue<int>que; que.push(cur); // vector<int>t; while (!que.empty()) { int now = que.front(); que.pop(); cout << ans[now] << " "; // t.push_back(ans[now]); for (int i = 0; i < G[now].size(); ++i) { que.push(G[now][i]); } } // if (check(t) != c) { // cout << "NO" << endl; // } else cout << "YES" << endl; } int deep[maxn]; void work() { cin >> len >> c; if (c > findmax(len)) { cout << -1 << endl; return; } LL cur = findmax(len); for (int i = 1; i <= len; ++i) { G[i].clear(); if (i != len) { G[i].push_back(i + 1); } deep[i] = i - 1; } while (!que.empty()) que.pop(); que.push(node(1, 0)); int impo = 1; for (int i = len; i >= 1 && cur > c; --i) { struct node t = que.front(); int one = i - t.deep - 2; int to = min(cur - c, one * 1LL); if (to <= 0) { cout << -1 << endl; return; } if (one == to) { G[t.cnt].push_back(i); deep[i] = deep[t.cnt] + 1; G[i].clear(); G[i - 1].clear(); if (G[t.cnt].size() == 2) { if (t.cnt == impo) impo++; que.pop(); que.push(node(G[t.cnt][0], t.deep + 1)); que.push(node(G[t.cnt][1], t.deep + 1)); } } else { G[i].clear(); G[i - 1].clear(); for (int j = 1; j <= len; ++j) { if (deep[i] == deep[j] + to + 1) { G[j].push_back(i); break; } } break; } cur -= to; } val = 1; show(1); bfs(1); // vector<int> t; // for (int i = 1; i <= len; ++i) { // cout << ans[i] << " "; // t.push_back(ans[i]); // } // cout << "****" << check(t); cout << endl; } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif int t; scanf("%d", &t); while (t--) work(); return 0; }
既然选择了远方,就要风雨兼程~
posted on 2017-02-16 14:47 stupid_one 阅读(311) 评论(0) 编辑 收藏 举报