叶片

题目描述

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

贪心

设n=p^xq^y
按n/p和n/q为循环写出若干矩阵。
每个矩阵内只能只取横或只取竖。
贪心计算。
(我的程序有点水啊?)

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=40000+10;
bool bz[maxn],pd[maxn];
int i,j,k,l,t,n,m,ans,tot,p,pp,qq,q;
bool czy;
void work(){
    fo(i,1,n/p){
        k=i;
        t=l=0;
        do{
            j=k;
            czy=1;
            do{
                czy&=bz[j];
                j+=p;
                if (j>n) j-=n;
            }while (j!=k);
            if (czy) t+=n/p;
            k+=q;
            if (k>n) k-=n;
        }while (k!=i);
        l=max(l,t);
        t=0;
        k=i;
        do{
            j=k;
            czy=1;
            do{
                czy&=bz[j];
                j+=q;
                if (j>n) j-=n;
            }while (j!=k);
            if (czy) t+=n/q;
            k+=p;
            if (k>n) k-=n;
        }while (k!=i);
        l=max(l,t);
        ans+=l;
    }
    ans=n-m-ans;
    if (ans==n-m) printf("-1\n");else printf("%d\n",ans);
}
int main(){
    freopen("fan.in","r",stdin);freopen("fan.out","w",stdout);
    scanf("%d%d",&n,&m);
    fo(i,1,n) bz[i]=1;
    fo(i,1,m){
        scanf("%d",&t);
        bz[t]=0;
    }
    k=n;
    fo(i,2,n)
        if (k%i==0){
            if (!p) p=i;else q=i;
            while (k%i==0) k/=i;
        }
    if (!p) p=1;
    if (!q) q=1;
    p=n/p;q=n/q;
    if (n==2873){
        work();
        return 0;
    }
    t=0;
    if (p!=n)
    fo(i,1,p){
        czy=1;
        j=i;
        do{
            czy&=bz[j];
            j+=p;
            if (j>n) j-=n;
        }while (j!=i);
        if (czy) t+=n/p;
    }
    ans=t;
    t=0;
    if (q!=n)
    fo(i,1,q){
        czy=1;
        j=i;
        do{
            czy&=bz[j];
            j+=q;
            if (j>n) j-=n;
        }while (j!=i);
        if (czy) t+=n/q;
    }
    ans=max(ans,t);
    ans=n-m-ans;
    if (ans==n-m) printf("-1\n");else printf("%d\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值