其他分享
首页 > 其他分享> > CF1305F Kuroni and the Punishment

CF1305F Kuroni and the Punishment

作者:互联网

zbk学长掏出来的“小清醒”题

我们通过审题

显然可以得出

看上去我可以知道操作次数最多为n

并且每个数字的操作次数最多为1

(使所有gcd()>1,最坏情况是都为互质的奇数

 

正解是:随机!!!

由于每个数字最多只有操作不操作的选项

如果是随机的话,一个元素就有0.5的几率会被操作

 

只要rand的次数多一些,就更接近

 

#include<bits/stdc++.h>

#define int long long
using namespace std;
const int N=1e6+7;

int p[N];
int a[N];
bool vis[N];
map<int ,bool >m;
vector<int >f;
int cnt,n,ans;

void init(int x)
{
    for(int i=2;i<=x;i++)
    {
        if(!vis[i])
        p[++cnt]=i;
    
    for(int j=1;j<=cnt&&i*p[j]<=x;j++)
    {
        vis[i*p[j]]=1;;
        if(!(i%p[j]))
        break;
    }
    
    }
    return ;
}

void solve(int x)
{
    for(int i=1;i<=cnt&&p[i]<=x;i++)
    {
        if(!(x%p[i]))
        {
            if(!m[p[i]])
            {
                m[p[i]]=1;
                f.emplace_back(p[i]);
            }
            while(!(x%p[i]))
            x/=p[i];
        }
        
    }
    
    if(x>1)
    {
        if(!m[x])
        {
            f.emplace_back(x);
            m[x]=1;
        }
        
    }
    
    return ;
    
}

int calc(int x)
{
    int re=0;
    for(int i=1;i<=n;i++)
    {
        if(a[i]<x)
        re+=x-a[i];
        else
        re+=min(a[i]%x,x-a[i]%x);
    }
    return re;
}


signed main()
{
    srand(time(NULL));
    init(1e6);
    ios::sync_with_stdio(false);
    cin>>n;
    
    for(int i=1;i<=n;i++)
    cin>>a[i];
    std::random_shuffle(a+1,a+n+1);
    
    for(int i =1;i<=min(n,(int )100);i++)
    {
        solve(a[i]);
        solve(a[i]-1);
        solve(a[i]+1);
    }
    ans=n;
    
    for(auto x: f)
    {
        ans=min(ans,calc(x));
    }
    cout<<ans;
    return 0;
}

 

标签:std,int,Kuroni,long,CF1305F,次数,最多为,操作,Punishment
来源: https://www.cnblogs.com/Hehe-0/p/15069641.html