zoukankan      html  css  js  c++  java
  • CodeForces 1305F. Kuroni and the Punishment (玄学 随机)

    传送门

    题意

    (a_1,a_2,...,a_n),你每次操作可以对其中一个数加减 (1),求使 (gcd(a_1,a_2,...,a_n)>1) 的最小操作次数。

    题解

    比较玄学,题解有英文的简单解释,没大看懂 (orz)
    首先我们称满足要求且次数最小的 (gcd) 为最优质因子。
    这里有一个玄学的结论,随机选一个 (a_i),最优质因子是 (a_i-1,a_i,a_i+1) 其中一个数的因子的概率为 (frac{1}{2})
    那么如果我们随机选了 (50) 个数,忽略重复情况,这些数的质因数中没有最优质因子的概率就是 ((frac{1}{2})^{50}),是非常小的。
    所以直接随机抽 (50) 个数,分解质因数,计算使所有 (a_i) 为该质因数倍数的花费,取最小花费,就是答案了。

    代码

    #include <iostream>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    #include <map>
    using namespace std;
    typedef long long LL;
    const int N=2e5+10;
    int n;
    LL a[N],ans;
    map<int,int> vis;
    
    int random(int n){
    	return (LL)rand()*rand()%n;
    }
    
    void check(LL x){
    	LL res=0;
    	for(int i=1;i<=n;i++)
    		if(a[i]>=x) res+=min(a[i]%x,x-a[i]%x);
    		else res+=x-a[i];
    	ans=min(ans,res);
    }
    
    int main(){
    	srand(time(0));
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    	ans=n;
    	for(int i=1;i<=min(100,n);i++){
    		int id=random(n+1);
    		LL temp=a[random(n)+1];
    		for(int k=-1;k<=1;k++){
    			LL num=temp+k;
    			if(num<1) continue;
    			for(LL j=2;j*j<=num;j++){
    				if(num%j!=0) continue;
    				if(!vis[j]) check(j),vis[j]=1;
    				while(num%j==0) num/=j;
    			}
    			if(num>1) check(num);
    		}
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    iOS8.1 To iOS8.2
    OAuth授权验证说明
    iOS消息推送
    Swift2
    Swift1
    数据结构,每次看都有不一样的体会
    修改CS、IP的指令(学习汇编)
    C,C++中的堆与栈
    12864显示菜单处理编程
    C编程常见的内存错误
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12409651.html
Copyright © 2011-2022 走看看