Advertisement
Guest User

vote.c

a guest
Sep 18th, 2015
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.74 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <limits.h>
  5.  
  6. typedef struct region {
  7.     unsigned *data;
  8.     unsigned width;
  9.     unsigned height;
  10.     unsigned pitch;
  11. } region;
  12.  
  13. enum direction { HORIZONAL, VERTICAL };
  14.  
  15. inline unsigned *
  16. value_at(region r, unsigned x, unsigned y)
  17. {
  18.     return &r.data[y * (r.width + r.pitch) + x];
  19. }
  20.  
  21. unsigned
  22. population(region r)
  23. {
  24.     unsigned total = 0;
  25.     for (unsigned y = 0; y < r.height; y++)
  26.         for (unsigned x = 0; x < r.width; x++)
  27.             total += *value_at(r, x, y);
  28.     return total;
  29. }
  30.  
  31. void
  32. split(region *a, region *b, enum direction dir, int v)
  33. {
  34.     region r = *a;
  35.     switch (dir) {
  36.         case HORIZONAL:
  37.             a->height = v;
  38.             b->height = r.height - v;
  39.             a->width = b->width = r.width;
  40.             a->pitch = b->pitch = r.pitch;
  41.             b->data = value_at(r, 0, v);
  42.             break;
  43.         case VERTICAL:
  44.             a->width = v;
  45.             b->width = r.width - v;
  46.             a->height = b->height = r.height;
  47.             a->pitch = r.pitch + b->width;
  48.             b->pitch = r.pitch + a->width;
  49.             b->data = value_at(r, v, 0);
  50.             break;
  51.     }
  52. }
  53.  
  54. bool
  55. in_region(region r, unsigned *p)
  56. {
  57.     if (p >= r.data) {
  58.         unsigned diff = p - (r.data - r.pitch);
  59.         unsigned y = diff / (r.width + r.pitch);
  60.         return y < r.height && (diff % (r.width + r.pitch)) >= r.pitch;
  61.     } else
  62.         return false;
  63. }
  64.  
  65. void
  66. colormap(unsigned nregion, region *regions, int colors[nregion])
  67. {
  68.     for (unsigned i = 0; i < nregion; i++)
  69.         colors[i] = -1;
  70.     unsigned alist[nregion][nregion];
  71.     for (unsigned i = 0; i < nregion; i++)
  72.         for (unsigned j = 0; j < nregion; j++)
  73.             alist[i][j] = 0;
  74.     // Build adjacency list (graph)
  75.     for (unsigned i = 0; i < nregion; i++) {
  76.         for (unsigned x = 0; x < regions[i].width; x++) {
  77.             unsigned *below = value_at(regions[i], x, -1);
  78.             unsigned *above = value_at(regions[i], x, regions[i].height);
  79.             for (unsigned j = i + 1; j < nregion; j++) {
  80.                 if (in_region(regions[j], below) ||
  81.                     in_region(regions[j], above))
  82.                     alist[i][j] = alist[j][i] = 1;
  83.             }
  84.         }
  85.         for (unsigned y = 0; y < regions[i].height; y++) {
  86.             unsigned *below = value_at(regions[i], -1, y);
  87.             unsigned *above = value_at(regions[i], regions[i].width, y);
  88.             for (unsigned j = i + 1; j < nregion; j++) {
  89.                 if (in_region(regions[j], below) ||
  90.                     in_region(regions[j], above))
  91.                     alist[i][j] = alist[j][i] = 1;
  92.             }
  93.         }
  94.     }
  95.     // Find 4-coloring by brute force
  96.     unsigned i = 0;
  97.     while (i < nregion) {
  98.         if (++colors[i] == 4) {
  99.             colors[i] = -1;
  100.             i--;
  101.             continue;
  102.         }
  103.         bool valid = true;
  104.         for (unsigned j = 0; valid && j < nregion; j++)
  105.             if (alist[i][j] && colors[i] == colors[j])
  106.                 valid = false;
  107.         if (valid)
  108.             i++;
  109.     }
  110. }
  111.  
  112. void
  113. print(region whole, unsigned nsub, region *sub)
  114. {
  115.     int colors[nsub];
  116.     colormap(nsub, sub, colors);
  117.     for (unsigned y = 0; y < whole.height; y++) {
  118.         for (unsigned x = 0; x < whole.width; x++) {
  119.             unsigned *p = value_at(whole, x, y);
  120.             unsigned color = 0;
  121.             for (unsigned i = 0; i < nsub; i++)
  122.                 if (in_region(sub[i], p))
  123.                     color = i;
  124.             printf("\x1b[%dm%2u\x1b[0m ",
  125.                    (int[]){91, 92, 93, 94}[colors[color]],
  126.                    *p);
  127.         }
  128.         putchar('\n');
  129.     }
  130. }
  131.  
  132. void
  133. evenly_split(region *a, region *b)
  134. {
  135.     region r = *a;
  136.     enum direction best_dir = 0;
  137.     unsigned best_v = 0;
  138.     unsigned best_diff = UINT_MAX;
  139.     unsigned best_length = UINT_MAX;
  140.     for (enum direction dir = 0; dir <= 1; dir++) {
  141.         unsigned max = dir == HORIZONAL ? r.height : r.width;
  142.         unsigned length = dir == HORIZONAL ? r.width : r.height;
  143.         for (unsigned v = 0; v < max; v++) {
  144.             region ra = r;
  145.             region rb;
  146.             split(&ra, &rb, dir, v);
  147.             int pop_a = population(ra);
  148.             int pop_b = population(rb);
  149.             unsigned diff = labs(pop_a - pop_b);
  150.             if (diff <= best_diff && length <= best_length) {
  151.                 best_dir = dir;
  152.                 best_v = v;
  153.                 best_diff = diff;
  154.                 best_length = length;
  155.             }
  156.         }
  157.     }
  158.     split(a, b, best_dir, best_v);
  159. }
  160.  
  161. int
  162. main(void)
  163. {
  164.     // Read input
  165.     unsigned nlines, nrows, ncols;
  166.     scanf("%u %u %u", &nlines, &nrows, &ncols);
  167.     unsigned data[ncols * nrows];
  168.     for (unsigned i = 0; i < nrows * ncols; i++)
  169.         scanf("%u", &data[i]);
  170.  
  171.     // Construct regions
  172.     struct region whole = {
  173.         .data = data,
  174.         .width = nrows,
  175.         .height = ncols,
  176.         .pitch = 0
  177.     };
  178.     struct region regions[nlines + 1];
  179.     regions[0] = whole;
  180.     unsigned nregions = 1;
  181.     for (unsigned i = 0; i < nlines; i++) {
  182.         unsigned next = 0;
  183.         unsigned next_pop = population(regions[0]);
  184.         // Find currently most populated region
  185.         for (unsigned r = 1; r < nregions; r++) {
  186.             unsigned pop = population(regions[r]);
  187.             if (pop > next_pop) {
  188.                 next = r;
  189.                 next_pop = pop;
  190.             }
  191.         }
  192.         evenly_split(&regions[next], &regions[nregions++]);
  193.     }
  194.  
  195.     // Print results
  196.     for (unsigned i = 0; i < nregions; i++)
  197.         printf("%u ", population(regions[i]));
  198.     putchar('\n');
  199.     print(whole, nregions, regions);
  200.     return 0;
  201. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement