• Kuroni and the Punishment CodeForces


    题意:

    给你n个数,你每次操作可以对一个数加1或者减1,让你求你最少需要操作多少次可以使这n个数的公因子大于1

    题解:

    正常方法就是枚举质因子(假设质因子为x),然后对于这个数组中的数a[i],让a[i]变成x的倍数的最小操作数为:

    1、如果a[i]不为0

    答案为:min(a[i]%x,x-a[i]%x)

    2、a[i]为0

    答案为:x

    后面的思路参考博客:https://blog.csdn.net/qq_41818939/article/details/104658566

    假设最大公约数为2时,每个数最多只需要操作一次就可以了,所以操作次数最多为n。所以需要操作次数≤1的数的数量≥n/2。
    一个数x操作次数≤1时候会变成x,x+1,x-1三种情况,所以我们可以随机一下需要操作次数≤1的数,这时候随机不到这种数的概率
    就是1/2T,T的数字大了之后概率就很小了,几乎不可能了。对每个随机到的数我们直接判断他的三种情况,每种情况就是枚举
    他的质因子,然后暴力计算需要操作的次数,最后取最小值就行了。
    复杂度为O(T*(sqrt(max)+n*log(max)))。

    代码:

     1 /*
     2 (神奇的随机算法)
     3 假设最大公约数为2时,每个数最多只需要操作一次就可以了,所以操作次数最多为n。所以需要操作次数≤1的数的数量≥n/2。
     4 一个数x操作次数≤1时候会变成x,x+1,x-1三种情况,所以我们可以随机一下需要操作次数≤1的数,这时候随机不到这种数的概率
     5 就是1/2T,T的数字大了之后概率就很小了,几乎不可能了。对每个随机到的数我们直接判断他的三种情况,每种情况就是枚举
     6 他的质因子,然后暴力计算需要操作的次数,最后取最小值就行了。
     7 复杂度为O(T*(sqrt(max)+n*log(max)))。
     8 ————————————————
     9 原文链接:https://blog.csdn.net/qq_41818939/java/article/details/104658566
    10 */
    11 #include<bits/stdc++.h>
    12 using namespace std;
    13 typedef long long ll;
    14 mt19937 rng_32(chrono::steady_clock::now().time_since_epoch().count());
    15 ll a[200005];
    16 int n;
    17 ll cal_ans(ll x)
    18 {
    19     ll ret=0;
    20     for (int i=0;i<n;i++)
    21     {
    22         ll tmp=a[i]%x;
    23         /*防止出现0
    24         如果a[i]是0,那么tmp也是0
    25         这样的话min(tmp,x-tmp)=0
    26         但是这样肯定是错的,因为a[i]是0的话,是没有因子的
    27         
    28         */
    29         if (a[i]!=tmp)
    30         ret+=min(tmp,x-tmp);
    31         else
    32         ret+=x-tmp;
    33     }
    34     return ret;
    35 }
    36 //计算质因子
    37 ll fac(ll x)
    38 {
    39     ll ret=1e18;
    40     ll en=sqrt(x+1ll);
    41     for(ll i=2;i<=en;i++)
    42     {
    43         if (x%i==0)
    44         {
    45             ret=min(ret,cal_ans(i));
    46             while(x%i==0)
    47             x/=i;
    48             if (x==1)
    49             break;
    50         }
    51     }
    52     if (x>1)
    53     ret=min(ret,cal_ans(x));
    54     return ret;
    55 }
    56 int main()
    57 {
    58     //printf("%d
    ",(0%5));
    59     cin>>n;
    60     for (int i=0;i<n;i++)
    61     scanf("%I64d",&a[i]);
    62     int T=10;
    63     ll ans=1e18;
    64     while (T--)
    65     {
    66         ll pos=rng_32()%n;
    67         //处理三种情况
    68         if (a[pos]>2)
    69         ans=min(ans,fac(a[pos]-1ll));
    70         ans=min(ans,fac(a[pos]));
    71         ans=min(ans,fac(a[pos]+1ll));
    72     }
    73     cout<<ans;
    74 }
    View Code
  • 相关阅读:
    Xamarin.Forms
    Docker Azure Kubernetes
    出现( linker command failed with exit code 1)错误总结(http://blog.csdn.net/hengshujiyi/article/details/21182813)
    UITextView学习笔记
    UIScrollView学习笔记
    如何学习ios(摘自知乎https://www.zhihu.com/question/20016551)
    iOS手势操作,拖动,轻击,捏合,旋转,长按,自定义(http://www.cnblogs.com/huangjianwu/p/4675648.html)
    触屏事件
    给UITextView添加链接
    IOS绘图详解(http://blog.163.com/wkyuyang_001/blog/static/10802122820133190545227/)
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/12807238.html
Copyright © 2020-2023  润新知