简单好玩的算法

求最大公约数的辗转相除法

    public static long gcd(long a,long b){
        long max=a>b?a:b;
        long min=a>b?b:a;
        if(max%min==0) return min;
        return gcd(min,max%min);
    }

利用的定理是:

设f(a,b)为a和b的最大公约数,则f(a,b)=f(b,a%b)。

证明:

对于a=b*q+r,有a-b*q=r。假设a和b的最大公约数为c,则a、b一定能被c整除,则m*a±n*b也一定能被c整除,故r也能被c整除。

求最大公约数的更相减损法

    public static long gcd1(long a,long b){
        if(a==b) return a;
        long max=a>b?a:b;
        long min=a>b?b:a;
        return gcd1(min,max-min);
    }

相比辗转相除法,这种方法不需要相比减法较为耗时的取模运算,但是这种方法不稳定,两个数相差很大或两个数相差很小时(其实相差很小会转变为相差很大的情况),这种方法就退化到O(n)了。

更相减损法原理不太懂……

用楼层测试鸡蛋的硬度

给两个蛋,有一百层楼,测试蛋在第几层楼扔下去会碎,如果没碎,蛋可以继续扔。求用最优策略,在最坏情况下要扔的次数。

可能题目描述不清楚,看不懂的百度一下吧

    public static int getTimeInWorstCase(int n){
        //对于第k层,蛋碎了,就从1到k-1层逐层往扔,这时候是k次;如果蛋没碎,就对n-k层继续之前操作。对每个k,取两者较大值;对所有k,取最小值。
        //map[n]= Math.min(Math.max(k,map[n-k]+1)),k=1...n-1,蛋在n层一定会碎,这是题目设定,所以扔到n-1就够了。蛋可能在1层都会碎,所以从1开始扔。
        //map[1]=1
        int[] map=new int[n+1];
        map[1]=1;
        for(int i=2;i<=n;i++){
            int curMin=Integer.MAX_VALUE;
            for(int j=1;j<i;j++){
                int temp=Math.max(j,map[i-j]+1);
                if(temp<curMin)
                    curMin=temp;
            }
            map[i]=curMin;
        }
        return map[n];
    }

还可以拓展到很多个蛋的情况。

对于两个蛋,还有一种不用动态规划的方法,但不懂为什么能这么做。

分为若干段,如果在第一个点a碎了,就从1开始到a-1,一共a次,如果第一个点没碎,就在第二个点b扔,b碎了,就从a+1到b-1扔;这是要保证a=b-a-1+2,即这一段长度为b-a=a-1后面的若干段以此类推。

所以对于n层,n<=a+(a-1)+(a-2)+…1,当n=100时,a>=14,得结果14

快速幂

    public static int myPow(int a, int b){
        int res=1,base=a;
        while(b!=0){
            if((b&1)!=0){

                res*=base;
            }
            base*=base;
            b=b>>1;
        }
        return res;
    }

原理:

2^11=(2^(2^0)) * (2^(2^1)) * (2^(2^3))

当二进制位为1时才相乘,为0乘以base。

时间: 2024-10-06 05:40:25

简单好玩的算法的相关文章

简单的PHP算法题(带扩充)

简单的PHP算法题(待完善…) 只打印0 具体个数由输入的参数n决定 如n=5就打印00000 根据n值打印n个0 打印一行 0101010101010101010101 具体个数由输入的参数n决定 如test.php?n=3打印010 根据n值打印010101… 实现1 00 111 0000 11111 for if 实现 <?php for ($i = 0; $i < 10; $i++) { for ($j = 0; $j <= $i; $j++) { if ($i % 2 ==

三种简单的排序算法

排序算法总是分不清,借了本数据结构来专门看了一下 说一下分类,主要有五类,插入排序,交换排序,选择排序,基数排序和归并排序 今天中午看了一下插入排序中的直接插入排序,交换排序的冒泡排序,选择排序中的冒泡排序 1.插入排序 将数组分成两个部分,一个是有序,一个是无序.将无序的每个元素插入到有序中,一共需要n - 1趟,最后一个元素不用计算 每一趟将第1个元素即array[i]元前面的i个元素比较,如果比array[i]大则后移一个位置.这样找到第i个元素的位置,插入 2.冒泡排序 将相邻两个元素比

运用简单的bloomfilter算法生成100万个不重复的随机数

本文中只是简单的体会bloomFilter算法的基本原理,设计实现一个生成100万个不重复的随机数. 选择3个分布均匀质数,在这里面质数的选择还是挺有讲究的,要注意不能太小,必须能够满足bloomfilter空间,不然整个空间都是1了还没有找到100万个不重复的随机数.不多说,上代码. #include<stdio.h> #include<stdlib.h> #include<time.h> #include<cstdbool> #define MAXNUM

HDOJ 2037简单的贪心算法

代码: #include<iostream> using namespace std; int main() { int n,s,t1[100],t2[100],i,t,j; while(cin>>n) { if(n==0) break; s=1; for(i=0;i<n;i++) cin>>t1[i]>>t2[i]; for(i=0;i<n;i++) for(j=i+1;j<n;j++) { if(t2[i]>t2[j]) { t=

冒泡排序算法和简单选择排序算法的js实现

之前已经介绍过冒泡排序算法和简单选择排序算法和原理,现在有Js实现. 冒泡排序算法 let dat=[5, 8, 10, 3, 2, 18, 17, 9]; function bubbleSort(data) { for(let i=0;i<data.length-1;i++){ for(let j=0;j<data.length-1-i;j++){ if(data[j]>data[j+1]){ [data[j],data[j+1]]=[data[j+1],data[j]]; } } }

使用tensorflow实现最简单的线性回归算法

1 #线性回归:用线性模型y=Wx+b拟合sin 2 import numpy as np 3 import matplotlib.pyplot as plt 4 import tensorflow as tf 5 6 #数据,标签 7 x_data = np.linspace(-2*np.pi,2*np.pi,300) 8 noise = np.random.normal(-0.01,0.05,x_data.shape) 9 y_label = np.sin(x_data) + noise 1

最快最简单的排序算法:桶排序

在我们生活的这个世界中到处都是被排序过的.站队的时候会按照身高排序,考试的名次需要按照分数排序,网上购物的时候会按照价格排序,电子邮箱中的邮件按照时间排序……总之很多东西都需要排序,可以说排序是无处不在.现在我们举个具体的例子来介绍一下排序算法. 首先出场的我们的主人公小哼,上面这个可爱的娃就是啦.期末考试完了老师要将同学们的分数按照从高到低排序.小哼的班上只有5个同学,这5个同学分别考了5分.3分.5分.2分和8分,哎考的真是惨不忍睹(满分是10分).接下来将分数进行从大到小排序,排序后是8

简单的神经网络算法-手写数字识别

本文通过BP神经网络实现一个简单的手写识别系统. 一.基础知识 1环境 python2.7 需要numpy等库 可利用sudo apt-get install python-安装 2神经网络原理 http://www.hankcs.com/ml/back-propagation-neural-network.html 讲的特别清楚,本实验过程中涉及矩阵运算都用numpy库的函数 3.js的基础知识 http://www.w3school.com.cn/tags/html_ref_canvas.a

四种简单的排序算法的php实现

无聊,用php写几个排序算法,算法介绍请移步这里,这里使用php实现了几个简单的,如下 //选择排序 function selection_sort($arr){ $len = count($arr); if($len <= 1) return $arr; for($i=0; $i<$len; $i++){ $min = $arr[$i]; $pos = $i; for($j=$i+1; $j<$len; $j++){ if($min > $arr[$j]){ $min = $ar