【jzoj5089】【GDOI2017第四轮模拟day2】【叶片】

探讨了一个关于圆涡轮叶片拆卸的问题,为确保涡轮重心仍位于中心,需计算最少还需拆卸多少个叶片。通过分析叶片质因子分布,并使用二维矩阵辅助计算,最终给出了解决方案。

题目大意

一个圆形涡轮上有N 个叶片均匀围成一圈,按顺时针1 到N 标号,其中有一些叶片损坏了。现在要把损坏的叶片给拆下来,但是为了使涡轮正常工作,它的重心还应该落在中心上。求最少还要再拆下几个叶片才能实现目标。

解题思路

对于一个质因子数的叶片,一定均衡分布,而一个叶片可以被两个质因子选,但现在只能被一个选,可以把关联的位置放在一个二维矩阵上,我们只可以保留行或列,保留了行就不能保留列,可以直接算。

code

#include<cstdio>
#include<algorithm>
#define min(a,b) ((a<b)?a:b)
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define fr(i,j) for(int i=begin[j];i;i=next[i])
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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值