Codeforces 488B - Candy Boxes (构造)

题意

如果有一个序列满足(a1 + a2 + a3 + a4) / 4 = (a2 + a3) / 2,并且等于a4 - a1那么这个序列符合条件的。

现在给出4个数中的n个,判断能否构造出这么一个序列。

思路

这是我写过最长的DIV2 - B( TДT)

解这个题目之前,首先要推出两条式子

x4=3x1
4x1=x2+x3

读取输入以后对他们从小到大排序

解释一下代码里的各个变量的含义。
input[],表示输入的数.
ans[i],表示最终序列第i位的数

先考虑n = 0的情况。
这时候随便输出一个序列即可。

n = 1时,直接把input[1]当成ans[1],根据第二条式子推出ans[4],然后就类似1 1 3 3直接得到答案。

n = 2时

  1. input[2](也就是两个输入里大的那个数,后面也一样)% 3 == 0。
    说明input[2]可以作为ans[4],然后ans[1]可以得出。这时候要判断一下ans[1]是否比input[1]小,如果不是的话这个序列就不存在了。
    这样一来就知道了三个数,可以直接输出ans[1] * 4 - input[1](题目没要求按位的顺序输出)和ans[1]了。
  2. input[2]不能整除3
    这时候将input[1]作为ans[1],判断input[2]是否小于ans[1] * 3。如果大于的话,显然无解。
    然后就可以求出ans[4],和上面一样可以输出剩下的一位数了。

n = 3时,总的思路和上面差不多,简略说了。
判断input[3]能否作为ans[4],分两种情况。最后判断得出的序列能否成立。

这里要注意当input[3] / 3 = input[1]这种情况还要讨论一下。

n = 4,直接判断。

好像写得啰嗦了。其实就是第一位和最后一位倒腾来倒腾去。


代码

 
 
  1. #include <cstdio>
  2. #include <stack>
  3. #include <set>
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. #include <queue>
  8. #include <functional>
  9. #include <cstring>
  10. #include <algorithm>
  11. #include <cctype>
  12. #include <string>
  13. #include <map>
  14. #include <iomanip>
  15. #include <cmath>
  16. #define LL long long
  17. #define ULL unsigned long long
  18. #define SZ(x) (int)x.size()
  19. #define Lowbit(x) ((x) & (-x))
  20. #define MP(a, b) make_pair(a, b)
  21. #define MS(arr, num) memset(arr, num, sizeof(arr))
  22. #define PB push_back
  23. #define F first
  24. #define S second
  25. #define ROP freopen("input.txt", "r", stdin);
  26. #define MID(a, b) (a + ((b - a) >> 1))
  27. #define LC rt << 1, l, mid
  28. #define RC rt << 1|1, mid + 1, r
  29. #define LRT rt << 1
  30. #define RRT rt << 1|1
  31. #define BitCount(x) __builtin_popcount(x)
  32. #define BitCountll(x) __builtin_popcountll(x)
  33. #define LeftPos(x) 32 - __builtin_clz(x) - 1
  34. #define LeftPosll(x) 64 - __builtin_clzll(x) - 1
  35. const double PI = acos(-1.0);
  36. const int INF = 0x3f3f3f3f;
  37. using namespace std;
  38. const double eps = 1e-6;
  39. const int MAXN = 1500 + 10;
  40. const int MOD = 1000007;
  41. const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
  42. typedef pair<int, int> pii;
  43. typedef vector<int>::iterator viti;
  44. typedef vector<pii>::iterator vitii;
  45. int ans[10], input[10];
  46. bool flag = true;
  47. bool Solve(int n)
  48. {
  49. if (n == 0)
  50. {
  51. puts("YES");
  52. printf("%d\n%d\n%d\n%d\n", 1, 1, 3, 3);
  53. }
  54. if (n == 1)
  55. {
  56. puts("YES");
  57. ans[1] = input[1], ans[4] = ans[1] * 3, ans[2] = ans[1], ans[3] = ans[4];
  58. for (int i = 2; i <= 4; i++) printf("%d\n", ans[i]);
  59. }
  60. if (n == 2)
  61. {
  62. if (input[2] % 3)
  63. {
  64. if (input[1] * 3 < input[2]) return flag = false;
  65. puts("YES");
  66. ans[1] = input[1], ans[4] = ans[1] * 3;
  67. int tmp = 4 * ans[1] - input[2];
  68. printf("%d\n%d\n", ans[4], tmp);
  69. }
  70. else
  71. {
  72. if (input[2] / 3 > input[1]) return flag = false;
  73. puts("YES");
  74. ans[1] = input[2] / 3;
  75. int tmp = 4 * ans[1] - input[1];
  76. printf("%d\n%d\n", ans[1], tmp);
  77. }
  78. }
  79. if (n == 3)
  80. {
  81. if (input[3] % 3)
  82. {
  83. if (input[1] * 3 < input[3]) return flag = false;
  84. for (int i = 1; i <= 3; i++) ans[i] = input[i];
  85. ans[4] = ans[1] * 3;
  86. if (4 * ans[1] != ans[2] + ans[3]) return flag = false;
  87. puts("YES");
  88. printf("%d\n", ans[4]);
  89. }
  90. else
  91. {
  92. if (input[3] / 3 > input[1]) return flag = false;
  93. if (input[3] / 3 == input[1])
  94. {
  95. puts("YES");
  96. printf("%d\n", input[1] * 4 - input[2]);
  97. return true;
  98. }
  99. ans[1] = input[3] / 3, ans[4] = input[3], ans[2] = input[1], ans[3] = input[2];
  100. if (4 * ans[1] != ans[2] + ans[3]) return flag = false;
  101. puts("YES");
  102. printf("%d\n", ans[1]);
  103. }
  104. }
  105. if (n == 4)
  106. {
  107. for (int i = 1; i <= 4; i++) ans[i] = input[i];
  108. if (4 * ans[1] == ans[2] + ans[3]) puts("YES");
  109. else flag = false;
  110. }
  111. }
  112. int main()
  113. {
  114. int n, i, j;
  115. scanf("%d", &n);
  116. for (i = 1; i <= n; i++) scanf("%d", &input[i]);
  117. sort(input + 1, input + n + 1);
  118. Solve(n);
  119. if (!flag)
  120. {
  121. puts("NO");
  122. return 0;
  123. }
  124. return 0;
  125. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值