• P8976 「DTOI-4」排列,贪心


    题目背景

    Update on 2023.2.1:新增一组针对 @yuanjiabao 的 Hack 数据,放置于 #21。

    Update on 2023.2.2:新增一组针对 @CourtesyWei 和 @bizhidaojiaosha 的 Hack 数据,放置于 #22。

    题目描述

    小 L 给你一个偶数 n 和两个整数a,b,请你构造一个长为 n 的排列 p,使得其满足 ∑2n​​pi​≥a 且2n​+1∑n​pi​≥b。

    输入格式

    本题有多组测试数据。

    第一行,一个整数 T,表示数据组数。

    对于每组数据:

    一行,三个整数 n,a,b。

    输出格式

    对于每组数据,如果无解,输出 -1;否则,输出一行,n 个整数,表示你构造出的排列 p。

    如有多解,输出任意一组均可。

    输入输出样例

    输入 #1复制

    2
    6 6 12
    6 8 14

    输出 #1复制

    1 6 2 5 3 4
    -1

    说明/提示

    本题开启 Special Judge。

    SubtaskSubtaskna,b分值
    112≤n≤10无特殊限制⁡20pts
    22无特殊限制a=b=0⁡10pts
    33同上a=0 或 b=010pts
    44同上无特殊限制60pts

    对于 100%的数据,2≤n,∑n≤105,0≤a,b≤2n(n+1)​,1≤T≤10,n 为偶数

    解析 :


    首先,如果(n+1)*n/2>a+b,那么肯定没有正确答案,所以直接返回输出-1即可
    否则,就有可能有可能有正确的答案;
    我们可以先处理前n/2个,使其满足 suma>=a ,当然为了是 sumb>=b,我们要尽可能使 suma >=a,的情况下尽可能的小,这样才能使后面的sumb尽可能的大;
    到这里,就已经有贪心的思路了:在满足要求的情况下尽可能的使答案最优,且满足二段性。
    所以我们可以贪心 suma ,使suma在满足题意的情况下最优,然后判断剩下的数是否满足 sumb>=b, 

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. using namespace std;
    15. typedef long long LL;
    16. const int N = 1e5 + 5;
    17. LL n, a, b;
    18. LL arr[N], brr[N];
    19. int main() {
    20. int T;
    21. scanf("%d", &T);
    22. while (T--) {
    23. memset(brr, 0, sizeof brr);
    24. scanf("%lld%lld%lld", &n, &a, &b);
    25. if (a + b > n * (n + 1) / 2) {
    26. cout << -1 << endl;
    27. continue;
    28. }
    29. LL sum = 0;
    30. for (int i = 1; i <= n / 2; i++) {
    31. arr[i] = i;
    32. sum += i;
    33. }
    34. LL t = n;
    35. for (int i = n/2; i >0 && a > sum; i--) {
    36. LL c = a - sum;
    37. if (c <= t - arr[i]) {
    38. arr[i] += c;
    39. sum += c;
    40. t--;
    41. break;
    42. }
    43. else {
    44. sum += t - arr[i];
    45. arr[i] = t;
    46. t--;
    47. }
    48. }
    49. if ((1 + n) * n / 2 - sum < b || sum < a) {
    50. cout << -1 << endl;
    51. continue;
    52. }
    53. for (int i = 1; i <= n / 2; i++) {
    54. brr[arr[i]] = 1;
    55. }
    56. for (int i = 1, j = n / 2 + 1; i <= n; i++) {
    57. if (brr[i] == 0)
    58. arr[j++] = i;
    59. }
    60. for (int i = 1; i < n; i++) {
    61. printf("%lld ", arr[i]);
    62. }
    63. printf("%lld\n", arr[n]);
    64. }
    65. return 0;
    66. }

     

  • 相关阅读:
    IDEA 调试远程服务
    WebSocketSession 发布订阅模式的学习
    机器学习基础原理
    《Python趣味工具》——ppt的操作(1)
    五、核支持向量机算法(NuSVC,Nu-Support Vector Classification)(有监督学习)
    【前端知识点】深浅拷贝
    【JVM基础14】——垃圾回收-强引用、软引用、弱引用、虚引用的区别
    数据集笔记:OpenCelliD(手机基站开放数据库)
    博图数值按照特定格式(“T000000”)转换成字符串
    华为回击:制裁无法阻挡中国科技创新 | 百能云芯
  • 原文地址:https://blog.csdn.net/Landing_on_Mars/article/details/134252665