题目
给定一个矩阵,求他达成至少一列或一行都为素数的操作数,每次操作可以让一个数加一
思路:将矩阵转化为该点到比他大的最小素数的距离。遍历矩阵求前缀和的最小值
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int prime[N],cnt;
bool st[N];
int a[510][510];
void shai()
{
for(int i=2;i<=100100;i++)
{
if(!st[i]) {
prime[cnt++]=i;
}
for(int j=0;prime[j]<=100100/i;j++)
{
st[i*prime[j]]=1;
if(i%prime[j]==0)
break;
}
}
}
int main()
{
int n,m;
cin>>n>>m;
shai();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
int num;
cin>>num;
int k=lower_bound(prime,prime+cnt,num)-prime;//如果直接遍历就会tle
a[i][j]=prime[k]-num;
}
int sum=0;
int sum2=0;
for(int i=1,j=1;j<=m;j++)
sum+=a[i][j];
for(int i=1;i<=n;i++)
{
sum2=0;
for(int j=1;j<=m;j++)
sum2+=a[i][j];
sum=min(sum,sum2);
}
for(int i=1;i<=m;i++)
{
sum2=0;
for(int j=1;j<=n;j++)
sum2+=a[j][i];
sum=min(sum,sum2);
}
printf("%d\n",sum);
}