题目大意
一个圆形涡轮上有N 个叶片均匀围成一圈,按顺时针1 到N 标号,其中有一些叶片损坏了。现在要把损坏的叶片给拆下来,但是为了使涡轮正常工作,它的重心还应该落在中心上。求最少还要再拆下几个叶片才能实现目标。
解题思路
对于一个质因子数的叶片,一定均衡分布,而一个叶片可以被两个质因子选,但现在只能被一个选,可以把关联的位置放在一个二维矩阵上,我们只可以保留行或列,保留了行就不能保留列,可以直接算。
code
using namespace std;
int const mn=2*1e4+9,inf=1e9;
int n,m,a[10],b[10],tag[mn],tag2[mn],f[mn];
int main(){
//freopen("fan.in","r",stdin);
//freopen("fan.out","w",stdout);
freopen("d.in","r",stdin);
freopen("d.out","w",stdout);
scanf("%d%d",&n,&m);int x;
fo(i,1,m){
scanf("%d",&x);
tag[x]++;
}
fo(i,1,n)if(tag[i]>1){
int bb;
bb++;
}
int tmp=n;a[2]=1;
fo(i,2,n)if(tmp%i==0){
a[++a[0]]=i;
while(tmp%i==0)tmp/=i;
if(tmp==1)break;
}
if((a[0]==1)&&(a[1]==n)){
printf("-1");
return 0;
}
int cnt=0,cnt2=0,ans=0;b[1]=n/a[1];b[2]=n/a[2];
fo(k,1,n/a[1]/a[2]){
cnt=cnt2=0;
fo(i,0,a[1]-1)f[i]=0;
fo(i,0,a[2]-1){
int ii=(i*b[2]+k-1)%n+1,ok=1;
fo(j,0,a[1]-1){
tag2[ii]=1;
if(tag[ii])f[j]=1,ok=0;
if((ii<1)||(ii>n)){
int bb;
bb++;
}
ii=(ii+b[1]-1)%n+1;
}
cnt+=ok;
}
fo(i,0,a[1]-1)cnt2+=!f[i];
if(a[2]==1)cnt2=0;
ans+=max(cnt*a[1],cnt2*a[2]);
}
if(!ans)printf("-1");
else printf("%d",n-m-ans);
return 0;
}