Advertisement
Guest User

Preventing Alzheimer's

a guest
Dec 8th, 2013
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.44 KB | None | 0 0
  1. /*
  2.  Petar 'PetarV' Velickovic
  3.  Task: Preventing Alzheimer's
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <math.h>
  8. #include <string.h>
  9. #include <iostream>
  10. #include <vector>
  11. #include <list>
  12. #include <string>
  13. #include <algorithm>
  14. #include <queue>
  15. #include <stack>
  16. #include <set>
  17. #include <map>
  18. #include <complex>
  19.  
  20. #define DPRINTC(C) printf(#C " = %c\n", (C))
  21. #define DPRINTS(S) printf(#S " = %s\n", (S))
  22. #define DPRINTD(D) printf(#D " = %d\n", (D))
  23. #define DPRINTLLD(LLD) printf(#LLD " = %lld\n", (LLD))
  24. #define DPRINTLF(LF) printf(#LF " = %.5lf\n", (LF))
  25.  
  26. using namespace std;
  27. typedef long long lld;
  28. typedef unsigned long long llu;
  29.  
  30. int t;
  31. int n, k;
  32. int a[25];
  33. int fin[25];
  34. int origSum;
  35. int sol;
  36.  
  37. int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311};
  38. lld masks[313];
  39.  
  40. lld getMask(int x)
  41. {
  42.     lld ret = 0LL;
  43.     for (int i=0;i < 64 && primes[i] <= x; i++)
  44.     {
  45.         if (x % primes[i] == 0) ret |= (1LL << i);
  46.     }
  47.     return ret;
  48. }
  49.  
  50. inline int max1(int a, int b)
  51. {
  52.     if (a > b) return a;
  53.     return b;
  54. }
  55.  
  56. void solve(int ind, int currSum, int prevNum, lld mask)
  57. {
  58.     if (ind == n)
  59.     {
  60.         if (currSum < sol) sol = currSum;
  61.         return;
  62.     }
  63.    
  64.     /* //DEBUG
  65.      printf("Recursing.\n");
  66.      DPRINTD(ind);
  67.      DPRINTD(currSum);
  68.      DPRINTD(prevNum);
  69.      printf("------------\n");
  70.     */
  71.    
  72.     int remNumbers = n - ind - 1;
  73.     int minNext = a[ind] / k;
  74.     if (a[ind] % k != 0) minNext++;
  75.     for (int i=max1(minNext , prevNum + 1);;i++)
  76.     {
  77.         if (currSum + k*(i + remNumbers*i + remNumbers*(remNumbers+1)/2) >= sol) return;
  78.         lld newMask = masks[i];
  79.         if (mask & newMask) continue;
  80.         solve(ind+1, currSum + k*i, i, (mask | newMask));
  81.     }
  82. }
  83.  
  84. int main()
  85. {
  86.     freopen("/Users/PetarV/preventing_alzheimers.txt","r",stdin);
  87.     freopen("/Users/PetarV/HackerCup/alzheimers_out.txt","w",stdout);
  88.    
  89.    
  90.     for (int num=2;num<=312;num++)
  91.     {
  92.         masks[num] = getMask(num);
  93.     }
  94.    
  95.     scanf("%d",&t);
  96.     for (int f=1;f<=t;f++)
  97.     {
  98.         scanf("%d%d",&n,&k);
  99.         origSum = 0;
  100.         for (int i=0;i<n;i++)
  101.         {
  102.             scanf("%d",&a[i]);
  103.             origSum += a[i];
  104.         }
  105.        
  106.         sort(a, a+n);
  107.        
  108.         sol = 987654321;
  109.         if (a[n-1] <= k)
  110.         {
  111.             sol = k * n;
  112.             if (a[0] == 0) sol -= k;
  113.             sol -= origSum;
  114.         }
  115.         else
  116.         {
  117.             int ii = 0;
  118.             while (a[ii] <= k)
  119.             {
  120.                 fin[ii] = k;
  121.                 ii++;
  122.             }
  123.             /* sfprtstpshr */
  124.             int prevII = ii;
  125.             int curr = k*ii;
  126.             int jj = 0;
  127.             for (; ii < n; ii++)
  128.             {
  129.                 int xx = k * primes[jj];
  130.                 while (a[ii] > xx)
  131.                 {
  132.                     jj++;
  133.                     xx = k * primes[jj];
  134.                 }
  135.                 fin[ii] = xx;
  136.                 jj++;
  137.             }
  138.             sol = 0;
  139.             for (int i=0;i<n;i++) sol += fin[i];
  140.             solve(prevII, curr, 1, 0LL);
  141.             sol -= origSum;
  142.         }
  143.        
  144.         printf("Case #%d: %d\n", f, sol);
  145.     }
  146.     return 0;
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement