Advertisement
Guest User

DevQuiz2011jp - sol

a guest
Sep 11th, 2011
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.47 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5.  
  6. #define LEFT_NODE 0
  7. #define RIGHT_NODE 1
  8.  
  9. struct _global {
  10.     int num;
  11. } globals;
  12.  
  13. struct bintree {
  14.     struct bintree *parent;
  15.     struct bintree *left;
  16.     struct bintree *right;
  17.     int *array;
  18.     int num;
  19.     int removed;
  20.     int point;
  21.     int depth;
  22. };
  23.  
  24. struct game {
  25.     struct bintree *root;
  26.     int *array;
  27.     int num;
  28.     int mindepth;
  29.     int ruleddepth;
  30. };
  31.  
  32. void freebintree(struct bintree *node)
  33. {
  34.     if (node->left)
  35.         freebintree(node->left);
  36.     if (node->right)
  37.         freebintree(node->right);
  38.     free(node->array);
  39.     free(node);
  40. }
  41.  
  42. void cleanup(struct game *game)
  43. {
  44.     freebintree(game->root);
  45.     if (game->array)
  46.         free(game->array);
  47.     free(game);
  48. }
  49.  
  50. FILE *readglobal(char *name)
  51. {
  52.     FILE *f;
  53.     char buf[1024];
  54.     f = fopen(name, "r");
  55.     fgets(buf, sizeof(buf), f);
  56.     sscanf(buf, "%d", &globals.num);
  57.     return f;
  58. }
  59.  
  60. int readnums(struct game *game, char *str)
  61. {
  62.     char *p;
  63.     int i, j;
  64.     int *array = game->array;
  65.  
  66.     for (i=j=0, p=str ; *p != '\0' ; i++, p++) {
  67.         if (*p == ' ' || *p == '\n') {
  68.             sscanf(str, "%d", array++);
  69.             str = p + 1;
  70.             if (*p == '\n')
  71.                 break;
  72.         }
  73.     }
  74.  
  75. #ifdef DEBUG
  76.     for (i=0, array=game->array ; i<game->num ; i++)
  77.         printf("%d ", *array++);
  78.     printf("\n");
  79. #endif
  80.  
  81.     return game->num;
  82. }
  83.  
  84. struct game *readgame(FILE *f)
  85. {
  86.     char *buf = (char *)calloc(1, 1024);
  87.     struct game *game = (struct game *)calloc(1, sizeof(struct game));
  88.  
  89.     fgets(buf, 1024, f);
  90.     sscanf(buf, "%d", &game->num);
  91.  
  92.     game->array = (int *)calloc(game->num, sizeof(int));
  93.  
  94.     fgets(buf, 1024, f);
  95.     readnums(game, buf);
  96.  
  97.     free(buf);
  98.     return game;
  99. }
  100.  
  101. struct bintree *newnode(struct game *game, struct bintree *parent)
  102. {
  103.     struct bintree *n;
  104.    
  105.     n = (struct bintree *)calloc(1, sizeof(struct bintree));
  106.  
  107.     n->parent = parent;
  108.     n->array  = (int *)calloc(game->num, sizeof(int));
  109.     if (parent) {
  110.         n->num = parent->num;
  111.         n->removed = parent->removed;
  112.         n->depth = parent->depth + 1;
  113.         memcpy(n->array, parent->array, sizeof(int) * n->num);
  114.     }
  115.     else {
  116.         n->num = game->num;
  117.         memcpy(n->array, game->array, sizeof(int) * n->num);
  118.     }
  119.  
  120.     return n;
  121. };
  122.  
  123. int evalremove5(int *array, int num, int removed)
  124. {
  125.     int i, point, count;
  126.    
  127.     for (i=count=point=0 ; i<num ; i++, array++) {
  128.         if (*array < 0)
  129.             continue;
  130.         if (*array % 5 == 0) {
  131.             count++;
  132.             if (*array % 2 == 1)
  133.                 point++;
  134.         }
  135.     }
  136.     if (count == num - removed)
  137.         return count;
  138.     return point;
  139. }
  140.  
  141. struct bintree *half(struct game *game, struct bintree *parent)
  142. {
  143.     int i, num;
  144.     int *p;
  145.  
  146.     struct bintree *node = newnode(game, parent);
  147.     parent->left = node;
  148.  
  149.     for (i=0, p=node->array, num=node->num ; i<num ; i++, p++) {
  150.         if (*p < 0)
  151.             continue;
  152.         *p /= 2;
  153.     }
  154.  
  155.     return node;
  156. }
  157.  
  158. struct bintree *remove5(struct game *game, struct bintree *parent)
  159. {
  160.     int i, num;
  161.     int *p;
  162.  
  163.     struct bintree *node = newnode(game, parent);
  164.     parent->right = node;
  165.  
  166.     for (i=0, p=node->array, num=node->num ; i<num ; i++, p++) {
  167.         if (*p < 0)
  168.             continue;
  169.         if (*p % 5 == 0) {
  170.             *p = -1;
  171.             node->removed++;
  172.         }
  173.     }
  174.  
  175.     return node;
  176. }
  177.  
  178. int ruledengine(struct game *game, struct bintree *node)
  179. {
  180.     struct bintree *next;
  181.  
  182.     if (evalremove5(node->array, node->num, node->removed)) {
  183.         next = remove5(game, node);
  184.     }
  185.     else {
  186.         next = half(game, node);
  187.     }
  188.    
  189.     if (next->num == next->removed) {
  190.         game->mindepth = game->ruleddepth = next->depth;
  191.         return next->depth;
  192.     }
  193.  
  194.     return ruledengine(game, next);
  195. }
  196.  
  197. int walkaroundengine(struct game *game, struct bintree *node)
  198. {
  199. #ifdef DEBUG
  200.     printf("%d\r", node->depth);
  201. #endif
  202.  
  203.     if (node->num == node->removed) {
  204.         if (node->depth < game->mindepth)
  205.             game->mindepth = node->depth;
  206.         return game->mindepth;
  207.     }
  208.  
  209.     if (node->depth == game->ruleddepth)
  210.         return node->depth;
  211.  
  212.     walkaroundengine(game, remove5(game, node));
  213.     walkaroundengine(game, half(game, node));
  214.  
  215.     freebintree(node->right);
  216.     freebintree(node->left);
  217.     node->right = node->left = NULL;
  218.  
  219.     return game->mindepth;
  220. }
  221.  
  222. int engine(struct game *game)
  223. {
  224.     game->root = newnode(game, NULL);
  225.     ruledengine(game, game->root);
  226.     freebintree(game->root);
  227.     game->root = newnode(game, NULL);
  228.     walkaroundengine(game, game->root);
  229.     return game->mindepth;
  230. }
  231.  
  232. int main(int argc, char *argv[])
  233. {
  234.     FILE *fp;
  235.     int i;
  236.    
  237.     fp = readglobal("soldata.txt");
  238.     for (i=0 ; i<globals.num ; i++) {
  239.         struct game *game = readgame(fp);
  240.         engine(game);
  241.         printf("%d\n", game->mindepth);
  242.         cleanup(game);
  243.     }
  244.    
  245.     fclose(fp);
  246.     return 0;
  247. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement