Advertisement
joric

nuke.c

Sep 26th, 2015
556
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.15 KB | None | 0 0
  1. /*
  2. https://dpaste.de/KTGe/raw
  3.  
  4. АО  «Котлин-Новатор»  является  крупным  разработчиком  и   производителем  бортовых комплексов,  вычислительных  систем,   процессоров  сигналов,  многофункциональных  РЛС,  систем электронной   индикации  тяжелых  транспортных  самолетов.
  5. ...
  6. Условия работы:
  7. - заработная плата от 35 т.р. для инженеров-программистов без опыта работы и от 50 т.р. с опытом работы;
  8. - рабочий день с 8-15 до 16-45;
  9. - оформление в соответствии с ТК РФ;
  10. - коллективный отпуск в июле;
  11. - работа в районе станции метро Площадь Александра Невского;
  12. ...
  13. Задача для соискателей:
  14.  
  15. Вы  оператор  пуска  ракет  на  ядерном  подводном  ракетоносце.  В   результате  ядерного  удара противника  вы  потеряли  возможность   воспользоваться  большей  частью  боезапаса  и  системой автоматического  наведения. Всё,  что  у  вас  теперь  есть  -  файл  с  координатами   целей,  одна  боеспособная  ракета,  и компилятор C  на  единственном  уцелевшем ноутбуке. Вам  нужно  вычислить  оптимальные  координаты   точки,  куда  следует  произвести  запуск, чтобы причинить   максимальный  ущерб противнику.   Вам известна характеристика  боевой   части  вашей  ракеты  -  радиус  поражения.
  16. Входные данные:
  17. - Текстовый файл с координатами целей в декартовой системе координат,  каждая строка файла это пара целых чисел от 0 до 99, записанных через  запятую.
  18. - Радиус  поражения  боевой  части  ракеты (целое число). Выходные данные:
  19. - Координаты оптимальной точки, куда следует произвести запуск.
  20. - Количество поражённых целей. Программа  должна  вызываться  из   командной  строки  с  двумя  параметрами  -  именем  файла с   координатами  и  радиусом поражения.
  21.  
  22. Вот  так:  nuke.exe coords.txt  10
  23. */
  24.  
  25. #include <stdio.h>
  26. #include <math.h>
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #include <time.h>
  30.  
  31. void test();
  32.  
  33. #define MAX_POINTS 10000
  34.  
  35. typedef struct {
  36.     double x,y;
  37. } point;
  38.  
  39. #define dist(p1,p2) (sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)))
  40.  
  41. int nuke(point * p, int points, int r, point * out)
  42. {
  43.     int coverage = 0;
  44.     int i, j, k, t, count;
  45.     point c;
  46.  
  47.     // for each pair of points: check 2 tangent circles, calc coverage
  48.     for (i=0;i<points;i++) for (j=i+1;j<points;j++)
  49.     {
  50.         double d = dist(p[i], p[j]);
  51.         if (d!=0 && d<=2*r)
  52.         {
  53.             double h = d/2;
  54.             double m = sqrt(r*r - h*h);
  55.  
  56.             for (t=0;t<2;t++)
  57.             {
  58.                 int sign = t ? 1 : -1;
  59.  
  60.                 c.x = (p[i].x+p[j].x)/2 + m * (p[i].y-p[j].y)/d * sign;
  61.                 c.y = (p[i].y+p[j].y)/2 + m * (p[j].x-p[i].x)/d * sign;
  62.  
  63.                 for (count=0, k=0; k<points; k++)
  64.                     if (dist(c, p[k])<=r)
  65.                         count++;
  66.  
  67.                 if (count>coverage)
  68.                 {
  69.                     coverage = count;
  70.                     out->x = c.x;
  71.                     out->y = c.y;
  72.                 }
  73.             }
  74.         }
  75.         else if (coverage==0) // no tangent
  76.             out->x = p[i].x, out->y = p[i].y;
  77.     }
  78.  
  79.     return coverage;
  80. }
  81.  
  82. int main(int argc, char ** argv)
  83. {
  84.     FILE * fp;
  85.     int i, coverage;
  86.     point c;
  87.     point p[MAX_POINTS];
  88.     char * fname = argc>1 ? argv[1] : "coords.txt";
  89.     int r = argc>2 ? atoi(argv[2]) : 10;
  90.  
  91.     if (argc==1)
  92.     {
  93.         printf("No arguments, running test...\n");
  94.         test();
  95.         return 1;
  96.     }
  97.  
  98.     fp = fopen (fname,"r");
  99.     if (!fp)
  100.         return 1;
  101.  
  102.     // load points
  103.     for (i=0;fscanf(fp,"%lf,%lf",&p[i].x,&p[i].y)==2 && i<MAX_POINTS;i++);
  104.  
  105.     // nuke
  106.     coverage = nuke(p, i, r, &c);
  107.  
  108.     // print results
  109.     printf("%d,%d\n", (int)c.x, (int)c.y);
  110.     printf("%d\n", coverage);
  111.  
  112.     fclose(fp);
  113.  
  114.     return 0;
  115. }
  116.  
  117. /* tests =============================================================== */
  118.  
  119. int g_width = 100;
  120. int g_height = 100;
  121. int * g_data;
  122. unsigned int g_color = 0xff00ff;
  123.  
  124. void DrawPixel(int x, int y)
  125. {
  126.     if (x>=0 && x<g_width && y>=0 && y<g_height)
  127.         g_data[y*g_width+x] = g_color;
  128. }
  129.  
  130. // https://en.wikipedia.org/wiki/Midpoint_circle_algorithm
  131. void DrawCircle(int x0, int y0, int radius)
  132. {
  133.   int x = radius;
  134.   int y = 0;
  135.   int decisionOver2 = 1 - x;   // Decision criterion divided by 2 evaluated at x=r, y=0
  136.  
  137.   while( y <= x )
  138.   {
  139.     DrawPixel( x + x0,  y + y0);
  140.     DrawPixel( y + x0,  x + y0);
  141.     DrawPixel(-x + x0,  y + y0);
  142.     DrawPixel(-y + x0,  x + y0);
  143.     DrawPixel(-x + x0, -y + y0);
  144.     DrawPixel(-y + x0, -x + y0);
  145.     DrawPixel( x + x0, -y + y0);
  146.     DrawPixel( y + x0, -x + y0);
  147.     y++;
  148.     if (decisionOver2<=0)
  149.     {
  150.       decisionOver2 += 2 * y + 1;   // Change in decision criterion for y -> y+1
  151.     }
  152.     else
  153.     {
  154.       x--;
  155.       decisionOver2 += 2 * (y - x) + 1;   // Change for y -> y+1, x -> x-1
  156.     }
  157.   }
  158. }
  159.  
  160. void saveTexture(char *filename, int w, int h, int *src)
  161. {
  162.     FILE *f;   
  163.     char buf[256];
  164.     int i,x,y,c;
  165.     unsigned char r, g, b, a;  
  166.     unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0};
  167.     unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};
  168.     unsigned char bmppad[3] = {0,0,0};
  169.  
  170.     unsigned char *img;
  171.     int filesize = 54 + 3*w*h;  //w is your image width, h is image height, both int
  172.     img = (unsigned char *)malloc(3*w*h);
  173.     memset(img,0,3*w*h);
  174.  
  175.     for(y=0; y<h; y++) for (x=0; x<w; x++)
  176.     {
  177.         c = src[(h - 1 - y) * w + x];
  178.         a = (c >> 24) & 0xFF;
  179.         r = (c >> 16) & 0xFF;
  180.         g = (c >> 8) & 0xFF;
  181.         b = c & 0xFF;
  182.         img[(x+y*w)*3+2] = (unsigned char)(r);
  183.         img[(x+y*w)*3+1] = (unsigned char)(g);
  184.         img[(x+y*w)*3+0] = (unsigned char)(b);
  185.     }
  186.  
  187.     bmpfileheader[ 2] = (unsigned char)(filesize);
  188.     bmpfileheader[ 3] = (unsigned char)(filesize>>8);
  189.     bmpfileheader[ 4] = (unsigned char)(filesize>>16);
  190.     bmpfileheader[ 5] = (unsigned char)(filesize>>24);
  191.  
  192.     bmpinfoheader[ 4] = (unsigned char)(w);
  193.     bmpinfoheader[ 5] = (unsigned char)(w>> 8);
  194.     bmpinfoheader[ 6] = (unsigned char)(w>>16);
  195.     bmpinfoheader[ 7] = (unsigned char)(w>>24);
  196.     bmpinfoheader[ 8] = (unsigned char)(h);
  197.     bmpinfoheader[ 9] = (unsigned char)(h>> 8);
  198.     bmpinfoheader[10] = (unsigned char)(h>>16);
  199.     bmpinfoheader[11] = (unsigned char)(h>>24);
  200.  
  201.     sprintf(buf, "%s.bmp", filename);
  202.     f = fopen(buf,"wb");
  203.     fwrite(bmpfileheader,1,14,f);
  204.     fwrite(bmpinfoheader,1,40,f);
  205.     for(i=0; i<h; i++)
  206.     {
  207.         fwrite(img+(w*(h-i-1)*3),3,w,f);
  208.         fwrite(bmppad,1,(4-(w*3)%4)%4,f);
  209.     }
  210.  
  211.     fclose(f);
  212.     free(img);
  213. }
  214.  
  215. int gen(point * p, int points, int w, int h)
  216. {
  217.     int i;
  218.     for (i=0;i<points;i++)
  219.         p[i].x = rand() % w, p[i].y = rand() % h;
  220.     return points;
  221. }
  222.  
  223. int draw(char * name, point * p, int points, int r, point c)
  224. {
  225.     int i;
  226.     int size = g_width*g_height;
  227.     g_data = (int*)malloc(size*sizeof(int));
  228.     memset(g_data, 0xff, size*sizeof(int));
  229.  
  230.     g_color = 0xffff0000;
  231.     DrawCircle((int)c.x, (int)c.y, r);
  232.  
  233.     g_color = 0xff000000;
  234.     for (i=0;i<points;i++)
  235.         DrawCircle(p[i].x, p[i].y, 5);
  236.  
  237.     saveTexture(name, g_width, g_height, g_data);
  238.  
  239.     free(g_data);
  240.     return 0;
  241. }
  242.  
  243. void test()
  244. {
  245.     point p[MAX_POINTS];
  246.     point c;
  247.     int i;
  248.     int r = 128;
  249.     int w = 512;
  250.     int h = 512;
  251.     int points = 15;
  252.  
  253.     time_t t;
  254.     srand((unsigned) time(&t));
  255.  
  256.     g_width = w;
  257.     g_height = h;
  258.  
  259.     for (i=0;i<50;i++)
  260.     {
  261.         char buf[256];
  262.         sprintf(buf,"nuke_%04d", i);
  263.  
  264.         r = 32 + rand() % 64;
  265.  
  266.         gen(p, points, w, h);
  267.         nuke(p, points, r, &c);
  268.         draw(buf, p, points, r, c);
  269.     }
  270. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement