fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. //必要があれば,関数をいくつでも追加して良い
  5.  
  6.  
  7.  
  8. //copy
  9. #define height 4
  10. #define MAX (1<<height) //ビットシフト演算 2^height と同じ
  11.  
  12.  
  13.  
  14. int t[MAX+1]; //配列外アクセス防止のためのダミーで+1
  15. int sz = 0;
  16.  
  17. void swap(int *x, int *y){
  18. int tmp = *x;
  19. *x = *y;
  20. *y = tmp;
  21. }
  22.  
  23. void initTree(int n){
  24. int i;
  25. for(i=0;i<MAX;i++){
  26. t[i] = -1;
  27. }
  28. }
  29.  
  30. void printA(){
  31. int i;
  32. for(i=1;i<=sz;i++) printf("%d ",t[i]);
  33. printf("\n");
  34. }
  35.  
  36. void printT(int i){
  37. int x = i;
  38. while(x/2!=0){
  39. printf(" ");
  40. x/=2;
  41. }
  42. printf("%d\n",t[i]);
  43. }
  44.  
  45. int goP(int i){
  46. if(i/2 == 0) return 0;
  47. else return i/2;
  48. }
  49.  
  50. int goL(int i){
  51. if(2*i >= MAX) return 0;
  52. else return 2*i;
  53. }
  54.  
  55. int goR(int i){
  56. if(2*i+1 >= MAX) return 0;
  57. else return 2*i+1;
  58. }
  59.  
  60. void preOrder(int i){
  61. if(t[i] == -1) return;
  62. printT(i);
  63. preOrder(goL(i));
  64. preOrder(goR(i));
  65. }
  66.  
  67. void inOrder(int i){
  68. if(t[i] == -1) return;
  69. inOrder(goL(i));
  70. printT(i);
  71. inOrder(goR(i));
  72. }
  73.  
  74. void postOrder(int i){
  75. if(t[i] == -1) return;
  76. postOrder(goL(i));
  77. postOrder(goR(i));
  78. printT(i);
  79. }
  80.  
  81. void insBT(int x){
  82. int k,i = 1;
  83. for(k=0;k<height;k++){
  84. if(t[i]==-1){
  85. t[i] = x;
  86. sz++;
  87. return;
  88. }
  89. if(x < t[i]) i = goL(i);
  90. else i = goR(i);
  91. }
  92. printf("Error : too high -> %d\n",x);
  93. }
  94.  
  95. //先頭の要素を取り出す
  96. //ダウンヒープ
  97. int popHeap() {
  98. if (sz == 0) {
  99. printf("heap is empty!\n");
  100. return -1;
  101. }
  102. int top = t[1];
  103. t[1] = t[sz];
  104. t[sz] = -1;
  105. sz--;
  106.  
  107. int i = 1;
  108. while (1) {
  109. int left = goL(i);
  110. int right = goR(i);
  111. int largest = i;
  112.  
  113. if (left <= sz && t[left] > t[largest]) largest = left;
  114. if (right <= sz && t[right] > t[largest]) largest = right;
  115.  
  116. if (largest == i) break;
  117. swap(&t[i], &t[largest]);
  118. i = largest;
  119. }
  120. return top;
  121. }
  122.  
  123. //末尾に要素を追加する
  124. //アップヒープ
  125. void pushHeap(int x) {
  126. if (sz >= MAX - 1) {
  127. printf("heap is full!\n");
  128. return;
  129. }
  130. sz++;
  131. t[sz] = x;
  132. int i = sz;
  133.  
  134. while (i > 1 && t[goP(i)] < t[i]) {
  135. swap(&t[i], &t[goP(i)]);
  136. i = goP(i);
  137. }
  138. }
  139.  
  140.  
  141. //copy
  142.  
  143. //solve
  144. int solve(){
  145. int ret;
  146. int i, x, n, q, sum_def=0;
  147. scanf("%d %d", &n, &q);
  148. // 木の初期化
  149. initTree(n);
  150. for (i = 0; i < n; i++) {
  151. scanf("%d", &x);
  152. pushHeap(x);
  153. sum_def+=x;
  154.  
  155. }
  156. sz = n;
  157.  
  158.  
  159. int max_def;
  160. for(i=0; i<q; i++){
  161. max_def=popHeap();
  162. pushHeap(max_def/2);
  163. printf("%d atack! %d -> %d\n", i+1, max_def, max_def/2);
  164. sum_def-=(max_def/2);
  165. }
  166.  
  167.  
  168. //ここにプログラムを書く
  169. //ret に答えを入れてメイン関数に返す
  170. //入力を受ける部分も自分で書いてください
  171. //今日の分を含め過去の授業のプログラムが
  172. //参考になるはずです
  173. ret=sum_def;
  174. return ret;
  175. }
  176. //solve
  177.  
  178. //メイン関数はいじらなくて良い
  179. int main(void){
  180. printf("%d\n",solve());
  181. return 0;
  182. }
Success #stdin #stdout 0s 5268KB
stdin
7 2
10 40 60 30 80 5 30
stdout
1 atack! 80 -> 40
2 atack! 60 -> 30
185