Advertisement
dmkozyrev

435_temp.cpp

Oct 30th, 2017
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.94 KB | None | 0 0
  1. /*
  2. Число называется счастливым, если какие-то определенные его цифры можно сложить так, чтобы получить половину суммы всех цифр.
  3.  
  4. Зафиксируем определенный набор цифр длины N. Количество чисел, получающихся из этого набора, равно n!/n_0!/n_1!/n_2!/.../n_k!, где n_k - количество k-й цифры в наборе.
  5.  
  6. Сумму, которую можно достичь, определяем из соображений динамического программирования.
  7. */
  8.  
  9. #include <iostream>
  10. #include <vector>
  11. #include <algorithm>
  12. #include <bitset>
  13. #include <cmath>
  14.  
  15. typedef long long Number;
  16.  
  17. void check(bool q) {
  18. if (!q) {
  19. throw 1;
  20. }
  21. }
  22.  
  23. Number fact(int n) {
  24. check(n >= 0);
  25. return n <= 1 ? 1 : fact(n-1) * n;
  26. }
  27.  
  28. Number C(int n, int k) {
  29. return fact(n) / fact(k) / fact(n-k);
  30. }
  31.  
  32. bool is_good_set(const std::vector<int>& set) {
  33. int sum = 0;
  34. for (int i = 0; i < (int)set.size(); ++i) {
  35. sum += i * set[i];
  36. }
  37. if (sum % 2 == 1) return false;
  38. std::bitset<301> is_sum(1);
  39. for (int i = 0; i <= (int)set.size(); ++i) {
  40. for (int c = 1; c <= set[i]; ++c) {
  41. is_sum |= (is_sum << i);
  42. }
  43. }
  44. return is_sum[sum / 2];
  45. }
  46.  
  47. void rec(int count, int curr_digit, int max_digit, std::vector<int>& set, int n, Number& answ) {
  48. if (curr_digit == max_digit) {
  49. set[curr_digit] = count;
  50. if (is_good_set(set)) {
  51. Number temp = fact(n);
  52. for (int i = 0; i <= max_digit; ++i) {
  53. temp /= fact(set[i]);
  54. }
  55. answ += temp;
  56. /*
  57. for (int i = 1; i <= max_digit; ++i) {
  58. printf(" %d[%d]", i, set[i]);
  59. }
  60. printf("\n");
  61.  
  62. std::cout << temp << std::endl;
  63. */
  64. }
  65.  
  66. return;
  67. }
  68.  
  69. for (int c = count; c >= 0; --c) {
  70. //printf(" %d[%d]", curr_digit, c);
  71. set[curr_digit] = c;
  72. rec(count-c, curr_digit+1, max_digit, set, n, answ);
  73. }
  74. }
  75.  
  76. Number fast_answer_without_zeros(int n, int k) {
  77. //printf("--- fast_answer_without_zeros(%d, %d) \n", n, k);
  78. Number answ = 0;
  79. std::vector<int> set(1+k);
  80. rec(n, 1, k, set, n, answ);
  81. return answ;
  82. }
  83.  
  84. Number fast_answer_with_zeros(int n, int k) {
  85. // printf("--- fast_answer_with_zeros(%d, %d) \n", n, k);
  86.  
  87. Number answ = 0;
  88. for (int zeros = 0; zeros <= n; ++zeros) {
  89. answ += fast_answer_without_zeros(n-zeros, k) * C(n, zeros);
  90. }
  91. return answ;
  92. /*
  93. Number answ = 0;
  94. std::vector<int> set(1+k);
  95. rec(n, 0, k, set, n, answ);
  96. return answ;
  97. */
  98. }
  99.  
  100. bool next(std::vector<int>& digits, int max_digit) {
  101. int i = 0;
  102. while (i < (int)digits.size() && digits[i] == max_digit) {
  103. digits[i] = 0;
  104. ++i;
  105. }
  106. if (i == (int)digits.size()) {
  107. return false;
  108. }
  109. ++digits[i];
  110. return true;
  111. }
  112.  
  113. std::vector<int> get_set(const std::vector<int>& digits, int max_digit) {
  114. std::vector<int> set(1+max_digit);
  115. for (auto d : digits) {
  116. ++set[d];
  117. }
  118. return set;
  119. }
  120.  
  121. Number slow_answer(int n, int k) {
  122. Number answer = 0;
  123. std::vector<int> digits(n, 0);
  124. do { /*
  125. printf("digits: ");
  126. for (int i = n-1; i >= 0; --i) {
  127. printf("%d", digits[i]);
  128. }
  129. printf("\n");
  130. printf(" set: ");
  131. */
  132. auto set = get_set(digits, k);
  133. /*
  134. for (int i = 0; i <= k; ++i) {
  135. printf("%d(%d) ", i, set[i]);
  136. }
  137. printf("\n");
  138. */
  139. if (is_good_set(set)) {
  140. /*
  141. for (int i = 0; i < (int)set.size(); ++i) {
  142. printf(" %d(%d)", i, set[i]);
  143. }
  144. printf("\n");
  145. */
  146. answer++;
  147. }
  148. /*
  149. for (int i = (int)digits.size()-1; i >= 0; --i) {
  150. printf("%d", digits[i]);
  151. }
  152. printf("\n");
  153. */
  154. } while (next(digits, k));
  155. return answer;
  156. }
  157.  
  158. int main() {
  159. int n = 11, k = 9;
  160. //std::cout << (long long)(std::pow(k+1ll,n)) << std::endl;
  161. std::cout << (long long)(std::pow(k+1ll, n) - fast_answer_with_zeros(n, k)) << std::endl;
  162. std::cout << (long long)(std::pow(k+1ll, n) - slow_answer(n,k)) << std::endl;
  163.  
  164. /*
  165. std::vector<int> count(1+k, 0);
  166. rec(n, 1, k, count);
  167. */
  168. /*
  169. int n, k;
  170. std::cin >> n >> k;
  171.  
  172. auto answ = fast_answer_with_zeros(n, k);
  173. std::cout << answ;
  174. */
  175. return 0;
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement