码迷,mamicode.com
首页 > 其他好文 > 详细

E1. Send Boxes to Alice (Easy Version)

时间:2019-12-07 21:39:06      阅读:74      评论:0      收藏:0      [点我收藏+]

标签:span   space   ==   while   集合   alice   include   const   name   

题解:

保存每个1的位置。然后记录1的总个数cnt,如果存在一个k使得这个k是每个集合的倍数,那么为了使操作次数最小,这个k应该是cnt的质因子。(因为都是每个集合的数目1,使每个集合的数目变为2需要的次数一定小于使每个集合数目变为4需要的次数)

枚举cnt的质因子x,即x个1构成一个新的集合。构成新集合的时候要是两边的1往中间凑(中位数)。剩下的就暴力。。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=1e18+7;
const ll N=1E5+7;
ll arr[N];
vector<ll >ve;
ll cal(ll x){
    ll sum=0;
    ll x1=x/2;
    for(ll i=0;i<ve.size();i+=x){
        for(ll j=i;j<i+x1;j++){
            sum+=ve[i+x1]-ve[j];
        }
        for(ll j=i+x-1;j>i+x1;j--){
            sum+=ve[j]-ve[i+x1];
        }
    }
    return sum;
}
void solve(){
    ll n;
    cin>>n;
    ll cnt=0;
    for(ll i=1;i<=n;i++){
        cin>>arr[i];
        if(arr[i]){
            cnt++;
            ve.push_back(i);
        }
    }
    if(cnt==1||n==1){
        cout<<-1<<endl;
        return ;
    }
    ll m=sqrt(cnt);
    ll sum=INF;
    for(ll i=2;i<=m;i++){
        if(cnt%i==0){
            sum=min(sum,cal(i));
            while(cnt%i==0) {
                cnt/=i;
            }
        }
    }
    if(cnt!=1){
        sum=min(sum,cal(cnt));
    }
    cout<<sum<<endl;
    return ;
}
int main(){
    solve();
    return 0;
}

 

E1. Send Boxes to Alice (Easy Version)

标签:span   space   ==   while   集合   alice   include   const   name   

原文地址:https://www.cnblogs.com/Accepting/p/12003080.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!