• ACM STUDY


    ACM学习<二>

     

    穷举算法思想:

        一句话:就是从所有可能的情况,搜索出正确的答案。
    步骤:
        1.对于一种可能的情况,计算其结果。
        2.判断结果是否满足,YES计算下一个,no继续步骤1,然后判断下个可能的情况。
    实例:
        孙子算经--鸡兔同笼:头35,脚94,几鸡几兔?
        
        
    复制代码
    #include <iostream>                                                       //头文件
    using namespace std;
    int qiongju(int head, int foot , int *chicken,int *rabbit)     //穷举算法
    {    
         int re,i,j;
         re=0;
         for(i=0;i<=head;i++)                                             //循环    
         {
              j=head-i;
              if(i*2+j*4==foot)                                             //判断,找到答案
              {
                   re=1;
                   *chicken=i;
                   *rabbit=j;
              }    
         }    
         return re;
    }
    int main()                                                                 //主函数
    {
         int chicken,rabbit,head,foot;
         int re;
         cout<<"鸡兔同笼问题:"<<endl;
         cout<<"输入头数:";
         cin >>head;
         cout<<"输入脚数:";
         cin >>foot;
         re =qiongju(head,foot,&chicken,&rabbit);                    //& 跟 qiongju()里面的 * 是不是表示  引用??
         if(re==1)
         {
              cout<<"鸡有:"<<chicken<<"只, 兔有"<<rabbit<<"只。" <<endl;
         }else
         {
              cout<<"无法求解!"<<endl;
         }
    }
    复制代码
     
    递推思想:
         1.根据已知的结果和关系,求解中间的结果。
         2.判断是否达到要求,如果没有达到,则继续根据已知的结果和关系求解中间结果。如果有的话,则表示寻找到一个正确的结果。
     实例:斐波那契数列———兔子产子
    复制代码
    #include <iostream>
    using namespace std;
    int fibonacci(int n)
    {
         if(n==1 || n==2)
         {
              return 1;
         }
         else
         {
              return fibonacci(n-1)+fibonacci(n-2);//递归调用
         }
    }
    int main()
    {
         int n,num;
         cout<<"斐波那契数列——兔子产子:"<<endl;
         cout<<"请输入时间:";
         cin >> n;
         num=fibonacci(n);
         cout<<"经过"<<n<<"年,可以产子"<<num<<""<<endl;
    }
    复制代码
     
    递归思想:
         递归算法,就是在程序中不断反复调用他自身的函数调用方式,这种函数也称为递归函数。
                         函数的递归调用用分两种情况:直接递归和间接递归。
                         直接递归:即在函数中调用函数本身。
                         间接递归:即间接地调用一个函数,如func_a调用了func_b,func_b又调用了func_a;间接递归用的不多。
         优点:代码间接清晰,可读性更好。用递归比循环表死简洁精炼。特别人工智能,八皇后问题,汉诺塔等适合用递归
         缺点:没有明显的减少代码规模和节省内存空间。 递归比非递归运行速度要慢一些。附加函数增加了时间的开销(要执行一系列的压栈出栈)。二者递归层次太深还可能导致堆栈溢出。
         实例:经典的阶乘
    复制代码
    #include <iostream>
    using namespace std;
    long fact(int n); //函数的声明
    int main()
    {
         int i;
         cout<<"请输入要求阶乘的一个整数:";
         cin >>i;
         cout<<i<<"的阶乘结果为"<<fact(i)<<endl;    
    }
    long fact(int n)
    {
         if(n<=1)
              return 1;
         else
              return n*fact(n-1);
    } 
    复制代码
     
    分治算法思想:
         基本思路:将一个计算复杂的问题分为规模较小,计算简单的小问题求解,然后综合各个小问题,得到最终问题的答案。
         基本过程:
         1.对于一个规模为N的问题若该问题可以容易的解决,那就直接解决。否则执行下面的步骤。
         2.将该问题分解为M个规模较小的子问题,这些子问题五项多里,并且与原问题形式相同。
         3.递归的解子问题。
         4.然后,将各子问题的解合并得到原问题的解。
    例子:
        问题:一个袋子30个硬币,一个假的,假的较轻。如何分辨假币?
        步骤:
              1.首先为每个币编号,分成两份,放在天平上。
              2.因为假币在轻的一方,继续将轻的重复上面的做法。
              3.直到剩下2个,直接用天平找出。
       
    复制代码
    #include <iostream>
    using namespace std;
    #define MAXNUM 4
    int FalseCoin(int coin[],int low,int high)
    {
         int i,sum1,sum2,sum3;
         int re;
         sum1=sum2=sum3=0;
         if(low+1==high)//最后一堆是两个的时候
         {
              if(coin[low]<coin[high])
              {
                   re=low+1;
                   return re;    
              }
              else
              {
                   re=high+1;
                   return re;
              }    
         }
         if((high-low+1)%2==0)//n为偶数
         {
              for(i=low;i<=low+(high-low)/2;i++)
              {
                   sum1+=coin[i];//前半段和    
              }
              for(i=low+(high-low)/2+1;i<=high;i++)
              {
                   sum2+=coin[i];//后半段和      
              }
              if(sum1>sum2)
              {
                   re=FalseCoin(coin,low+(high-low)/2+1,high);
                   return re;
              }
              else if(sum1<sum2)
              {
                   re=FalseCoin(coin,low,low+(high-low)/2);    
                   return re;
              }
              else
              {
                  
              }    
         }
         else    //n为奇数
         {
              for(i=low;i<=low+(high-low)/2-1;i++)
              {
                   sum1+=coin[i];//前半段和
              }
              for(i=low+(high-low)/2+1;i<=high;i++)
              {
                   sum2+=coin[i];//后半段和 
              }
              sum3=coin[low+(high-low)/2];
              if(sum1>sum2)
              {
                   re=FalseCoin(coin,low+(high-low)/2+1,high);
                   return re;
              }
              else if(sum1<sum2)
              {
                   re=FalseCoin(coin,low,low+(high-low)/2-1);    
                   return re;
              }
              else
              {
                  
              }
              if(sum1+sum3==sum2+sum3)
              {
                   re=low+(high-low)/2+1;
                   return re;
              }
         }    
    }
    int main()
    {
          int coin[MAXNUM];
           int i,n;
           int place;
           cout<<"分治法求假币问题!"<<endl;
           cout<<"请输入币的个数:";
          cin >>n;
          cout<<"请输入币真假的重量:";
          for(i=0;i<n;i++)
          {
              cin >> coin[i];
               //scanf("%d",&coin[i]);
          }
          place =FalseCoin(coin,0,n-1);
          cout<<"位子实在上述的第"<<place<<"个是假的"<<endl;
    }
    复制代码
     
    概率算法思想:
         1.将问题转化为相应的几何图形S,S的面积是容易计算的。问题往往是对应的集合图形的S1的面积,
         2.然后向几何随机撒点。
         3.统计S S1的点数,根据关系得出结果。
         4.判断是否达到精度,否执行2步骤,是 结束
              4种形式:数值概率算法,蒙特卡罗算法 ,拉斯维加斯算法,舍伍德算法。
        蒙特卡罗概率算法 计算PI:
    复制代码
    #include <iostream>
    #include <time.h>
    using namespace std;
    double MontePI(int n)
    {
         double PI;
         double x,y;
         int i , sum;
         sum = 0;
         srand(time(NULL));
         for(i=1;i<n;i++)
         {
              x=(double)rand()/RAND_MAX;
              y=(double)rand()/RAND_MAX;
              if(x*x+y*y<=1)
                   sum++;     
         }
         PI=4.0*sum/n;
         return PI;
    }
    int main()
    {
         int n;
         double PI;
         cout<<"蒙特卡罗概率算法 计算PI"<<endl;
         cout<<"输入撒点的数量:";
         cin >> n;
         PI=MontePI(n);
         cout<<PI<<endl;
    }
    复制代码
     
     
  • 相关阅读:
    单例模式
    HashSet、LinkedHashSet、SortedSet、TreeSet
    ArrayList、LinkedList、CopyOnWriteArrayList
    HashMap、Hashtable、LinkedHashMap
    andrew ng machine learning week8 非监督学习
    andrew ng machine learning week7 支持向量机
    andrew ng machine learning week6 机器学习算法理论
    andrew ng machine learning week5 神经网络
    andrew ng machine learning week4 神经网络
    vue组件监听属性变化watch方法报[Vue warn]: Method "watch" has type "object" in the component definition. Did you reference the function correctly?
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3386155.html
Copyright © 2020-2023  润新知