牛牛的构造(构造)
题目描述:
请你给出一个长度为
输入描述:
第一行输入两个整数
输出描述:
输出一行,一个长度为
样例1:
input:
3 1
output:
1 3 2
说明:
样例2:
input:
1 100
output:
-1
AC代码:
#include <bits/stdc++.h> using namespace std; const int N = 1e6 + 10; int k, n; int a[N]; // b[i]表示i最多能形成多少个二元组 // 即i, i - 1, i - 2,..., 1这样的排列中i能形成多少个二元组 int b[N]; int main() { scanf("%d%d", &n, &k); int num = 0; // 对数组b进行构造 for(int i = 1; i <= n; i *= 2) b[i + 1] = 1; for(int i = 1; i <= n; i ++) b[i] = b[i - 1] + b[i]; // 对n, n - 1, n - 2,..., 1这样的数组能形成的二元组的数量和相加 // num为这个1到n的排列能形成的最多的二元组的数量 for(int i = 1; i <= n; i ++) num += b[i]; // num < k代表这个排列不能形成k个二元组 if(num < k) { printf("-1"); return 0; } // 如果num >= k则可以 // 得到的数组的形式为一个递减区间和一个递增区间 // 则这个数组的能形成的二元组的数量为: // 递减区间的数能形成的二元组的数量的和 // 递增区间不会形成二元组 // 如:7 6 5 1 2 3 4的二元组的数量为b[7] + b[6] + b[5] vector<int> dec, inc; // 从后往前枚举 for(int i = n; i >= 1; i --) { // 只要k >= b[i]就把i放入递减区间 if(k >= b[i]) { k -= b[i]; dec.push_back(i); } // 否则就放入递增区间 else { inc.push_back(i); } } // 因为是从后往前枚举,最后要将递增区间翻转 reverse(inc.begin(), inc.end()); // 输出递增递减区间 for(auto j : dec) printf("%d ", j); for(auto j : inc) printf("%d ", j); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】