二分查找/暴力 Codeforces Round #166 (Div. 2) B. Prime Matrix

 

题目传送门

  1 /*
  2     二分查找/暴力:先埃氏筛选预处理,然后暴力对于每一行每一列的不是素数的二分查找最近的素数,更新最小值
  3 */
  4 #include <cstdio>
  5 #include <cstring>
  6 #include <algorithm>
  7 using namespace std;
  8 
  9 const int MAXN = 5e2 + 10;
 10 const int MAXM = 1e6 + 10;
 11 const int INF = 0x3f3f3f3f;
 12 int a[MAXN][MAXN];
 13 int mn_r[MAXN];
 14 int mn_c[MAXN];
 15 bool is_prime[MAXM];
 16 int prime[MAXM];
 17 int n, m, x, y;
 18 int tot;
 19 
 20 void solve(void)
 21 {
 22     for (int i=1; i<=1e6; ++i)    is_prime[i] = true;
 23     is_prime[1] = false;
 24     for (int i=2; i<=1e6; ++i)
 25     {
 26         if (is_prime[i])
 27         {
 28             prime[++tot] = i;
 29             for (int j=i*2; j<=1e6; j+=i)    is_prime[j] = false;
 30         }
 31     }
 32 }
 33 
 34 bool check_r(void)
 35 {
 36     memset (mn_r, 0, sizeof (mn_r));
 37     bool ok = true;
 38     for (int i=1; i<=n; ++i)
 39     {
 40         for (int j=1; j<=m; ++j)
 41         {
 42             if (!is_prime[a[i][j]])
 43             {
 44                 ok = false;    mn_r[j]++;
 45             }
 46         }
 47     }
 48 
 49     return ok;
 50 }
 51 
 52 bool check_c(void)
 53 {
 54     memset (mn_c, 0, sizeof (mn_c));
 55     bool ok = true;
 56     for (int j=1; j<=m; ++j)
 57     {
 58         for (int i=1; i<=n; ++i)
 59         {
 60             if (!is_prime[a[i][j]])
 61             {
 62                 ok = false;    mn_c[j]++;
 63             }
 64         }
 65     }
 66 
 67     return ok;
 68 }
 69 
 70 int sum_r(void)
 71 {
 72     int ans = INF;    int tmp = 0;
 73     for (int i=1; i<=n; ++i)
 74     {
 75         tmp = 0;    bool ok = true;
 76         for (int j=1; j<=m; ++j)
 77         {
 78             if (!is_prime[a[i][j]])
 79             {
 80                 int p = lower_bound (prime+1, prime+1+tot, a[i][j]) - prime;
 81                 if (p <= tot)    tmp += prime[p] - a[i][j];
 82                 else    {ok = false;    break;}
 83             }
 84         }
 85         if (ok) ans = min (ans, tmp);
 86     }
 87 
 88     return ans;
 89 }
 90 
 91 int sum_c(void)
 92 {
 93     int ans = INF;    int tmp = 0;
 94     for (int j=1; j<=m; ++j)
 95     {
 96         tmp = 0;    bool ok = true;
 97         for (int i=1; i<=n; ++i)
 98         {
 99             if (!is_prime[a[i][j]])
100             {
101                 int p = lower_bound (prime+1, prime+1+tot, a[i][j]) - prime;
102                 if (p <= tot)    tmp += prime[p] - a[i][j];
103                 else    {ok = false;    break;}
104             }
105         }
106         if (ok) ans = min (ans, tmp);
107     }
108 
109     return ans;
110 }
111 
112 int main(void)        //Codeforces Round #166 (Div. 2) B. Prime Matrix
113 {
114 //    freopen ("B.in", "r", stdin);
115 
116     solve ();
117     while (scanf ("%d%d", &n, &m) == 2)
118     {
119         for (int i=1; i<=n; ++i)
120         {
121             for (int j=1; j<=m; ++j)
122                 scanf ("%d", &a[i][j]);
123         }
124 
125         if (check_r () || check_c ())    {puts ("0");    continue;}
126         else    printf ("%d\n", min (sum_r (), sum_c ()));
127     }
128 
129     return 0;
130 }

 

posted @ 2015-06-09 15:11  Running_Time  阅读(224)  评论(0编辑  收藏  举报