zoukankan      html  css  js  c++  java
  • 蓝桥杯——算法分析

    蓝桥杯比赛:对算法题进行一些整理,以C语言为主。

    题目:

    1.杨辉三角形

    在屏幕上显示杨辉三角形
    1
    1 1
    1 2 1
    1 3 3 1
    1 4 6 4 1
    1 5 10 10 5 1
    ......................................
    问题分析与算法设计
    杨辉三角形中的数,正是(x+y)的N次方幂展开式各项的系数。本题作为程序设计中具有代表性的题目,求解的方法很多,这里仅给出一种。

    从杨辉三角形的特点出发,可以总结出:
    1)第N行有N+1个值(设起始行为第0行)
    2)对于第N行的第J个值:(N>=2)
    当J=1或J=N+1时:其值为1
    J!=1且J!=N+1时:其值为第N-1行的第J-1个值与第N-1行第J个值之和
    将这些特点提炼成数学公式可表示为:
    1 x=1或x=N+1
    c(x,y)= c(x-1,y-1)+c(x-1,y) 其它
    本程序应是根据以上递归的数学表达式编制的。

    源代码:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 
     4 int c(int x,int y)     /*求杨辉三角形中第x行第y列的值*/
     5 {
     6     int z;
     7     if((y==1)||(y==x+1))  return 1;  /*若为x行的第1或第x+1列,则输出1*/
     8     z=c(x-1,y-1)+c(x-1,y);          /*否则,其值为前一行中第y-1列与第y列值之和*/
     9     return z;
    10 }
    11 void main()
    12 {
    13     int i,j,n=13;
    14     printf("N=");
    15     while(n>12)
    16         scanf("%d",&n);     /*控制输入正确的值以保证屏幕显示的图形正确*/
    17     for(i=0;i<=n;i++)       /*控制输出N行*/
    18     {
    19         for(j-0;j<24-2*i;j++) printf(" ");  /*控制输出第i行前面的空格*/
    20         for(j=1;j<i+2;j++) printf("%4d",c(i,j));    /*输出第i行的第j个值*/
    21         printf("
    ");
    22     }
    23     system("pause");
    24 }

    运行结果:

     2.歌德巴赫猜想
         验证:2000以内的正偶数都能够分解为两个素数之和(即验证歌德巴赫猜想对2000以内的正偶数成立)。
    问题分析与算法设计:
           为了验证歌德巴赫猜想对2000以内的正偶数都是成立的,要将整数分解为两部分,然后判断出分解出的两个整数是否均为素数。若是,则满足题意;否则重新进行分解和判断。
        程序中对判断是否为素数的算法进行了改进,对整数判断“用从2开始到该整数的一半”改为“2开始到该整数的平方根”。原因何在请自行分析。

    源代码:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<math.h>
     4 int flag(int n);
     5 void main()
     6 {
     7     int i,n;
     8     for(i=4;i<=2000;i+=2)/*范围,且保证为偶数时执行循环体*/
     9     {
    10         for(n=2;n<i;n++)         /*将偶数i分解为两个整数*/
    11             if(flag(n))         /*分别判断两个整数是否均为素数*/
    12             {
    13                 if(flag(i-n))
    14                 {
    15                     printf("%10d=%d+%d",i,n,i-n);   /*若均是素数则输出*/
    16                     break;
    17                 }
    18             
    19             }
    20                 
    21             if(n==i) 
    22             {
    23                 printf("error %d",i);
    24                 break;
    25             }
    26     }
    27 } 
    28 int flag(int i)           /*判断是否为素数*/
    29 {
    30     int j;
    31     if(i<=1)return 0;
    32     if(i==2)return 1;
    33     if(!(i%2))return 0;     /*if no,return 0*/
    34     for(j=3;j<=(int)(sqrt((double)i)+1);j+=2)/*求平方根*/
    35     {
    36         if(!(i%j))/*判断是否为素数*/
    37         {
    38             return 0;
    39         }
    40             
    41     }   
    42     system("pause");
    43     return 1;              /*if yes,return 1*/
    44 
    45 }

    运行结果:

    3.马克思手稿中的数学题
       
     马克思手稿中有一道趣味数学问题:有30个人,其中有男人、女人和小孩,在一家饭馆吃饭花了50先令;每个男人花3先令,每个女人花2先令,每个小孩花1先令;问男人、女人和小孩各有几人?

    题目分析与算法设计:
        设x,y,z分别代表男人、女人和小孩。按题目的要求,可得到下面的方程:
                       x+y+z=30            (1)
                       3x+2y+z=50          (2)
        用方程程序求此不定方程的非负整数解,可先通过(2)-(1)式得:
                       2x+y=20             (3)
    (3)式可知,x变化范围是0~10

    源代码:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 void main()
     4 {
     5     int x,y,z,count=0;
     6     printf("            Men      Women     Children
    ");
     7     printf("==========================================
    ");
     8     for(x=0;x<=10;x++)
     9     {
    10         y=20-2*x;                     /*x定值据(3)式求y*/
    11         z=30-x-y;                     /*由(1)式求z*/
    12         if(3*x+2*y+z==50)             /*当前得到的一组解是否满足式(2)*/
    13             printf(" %2d:         %d         %d         %d
    ",++count,x,y,z);
    14     }
    15     system("pause");
    16 }

    运行结果:



    4.谁是窃贼
        公安人员审问四名窃贼嫌疑犯。已知,这四人当中仅有一名是窃贼,还知道这四人中每人要么是诚实的,要么总是说谎的。在回答公安人员的问题中:
            甲说:“乙没有偷,是丁偷的。”
            乙说:“我没有偷,是丙便的。”
            丙说:“甲没有偷,是乙偷的。”
            丁说:“我没有偷。”
        请根据这四人的答话判断谁是盗窃者。

    问题分析与算法设计:
        假设A、B、C、D分别代表四个人,变量的值为1代表该人是窃贱。
        由题目已知:四人中仅有一名是窃贱,且这四个人中的每个人要么说真话,要么说假话,而由于甲、乙、丙三人都说了两句话:“X没偷,X偷了”,故不论该人是否说谎,他提到的两人中必有一人是小偷。故在列条件表达式时,可以不关心谁说谎,谁说实话。这样,可以列出下列条件表达式:
            甲说:”乙没有偷,是丁偷的。”        B+D=1
            乙说:“我没有偷,是丙偷有。”        B+C=1
            丙说:“甲没有偷,是乙偷的。”        A+B=1
            丁说:“我没有偷。”                  A+B+C+D=1
        其中丁只说了一句话,无法判定其真假,表达式反映了四人中仅有一名是窃贱的条件。
    源代码:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 void main()
     4 {
     5     int i,j,a[4];
     6     for(i=0;i<4;i++)            /*假定只有第i个人为窃贱*/
     7     {
     8         for(j=0;j<4;j++)        /*将第i个人设置为1表示窃贱,其余为0*/
     9             if(j==i)a[j]=1;
    10             else a[j]=0;
    11         if(a[3]+a[1]==1&&a[1]+a[2]==1&&a[0]+a[1]==1)   /*判断条件是否成立*/
    12         {
    13             printf("The thief is  ");              /*成立*/
    14             for(j=0;j<=3;j++)                   /*输出计算结果*/
    15                 if(a[j])printf("%c.",j+'A');
    16             printf("
    ");
    17         }
    18     }
    19     system("pause");
    20 }

    运行结果:



    5.迷语博士的难题(1)
        诚实族和说谎族是来自两个荒岛的不同民族,诚实族的人永远说真话,而说谎族的人永远说假话。迷语博士是个聪明的人,他要来判断所遇到的人是来自哪个民族的。
        迷语博士遇到三个人,知道他们可能是来自诚实族或说谎族的。为了调查这三个人是什么族的,博士分别问了他们的问题,这是他们的对话:
        问第一个人:“你们是什么族?”,答:“我们之中有两个来自诚实族。”第二个人说:“不要胡说,我们三个人中只有一个是诚实族的。”第三个人听了第二个人的话后说:“对,就是只有一个诚实族的。”
        请根据他的回答判断他们分别是哪个族的。

    问题分析与算法设计:
        假设这三个人分别为A、B、C,若说谎其值为0,若诚实,其值为1。根据题目中三个人的话可分别列出:
            第一个人: a&&a+b+c==2||!a&&a+b+c!=2
            第二个人: b&&a+b+c==1||!b&&a+b+c!=1
            第三个人: c&&a+b+c==1||!c&&a+b+c!=1
        利用穷举法,可以很容易地推出结果。
    源代码:

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 void main()
     4 {
     5     int a,b,c;
     6     for(a=0;a<=1;a++)       /*穷举每个人是说谎还是诚实的全部情况*/
     7         for(b=0;b<=1;b++)    /*说谎:0   诚实:1*/
     8             for(c=0;c<=1;c++)
     9                 if((a&&a+b+c==2||!a&&a+b+c!=2)    /*判断是否满足题意*/
    10                     &&(b&&a+b+c==1||!b&&a+b+c!=1)
    11                     &&(c&&a+b+c==1||!c&&a+b+c!=1))
    12                 {
    13                     printf("A is a %s.
    ",a?"honest":"lier");    /*输出判断结果*/
    14                     printf("B is a %s.
    ",b?"honest":"lier");
    15                     printf("C is a %s.
    ",c?"honest":"lier");
    16                 }
    17     system("pause");
    18 }

    运行结果:


    6.小结

    数学题的逻辑 !!!


        

  • 相关阅读:
    hibernate_0100_HelloWorld
    MYSQL子查询的五种形式
    JSF是什么?它与Struts是什么关系?
    nop指令的作用
    htmlparser实现从网页上抓取数据(收集)
    The Struts dispatcher cannot be found. This is usually caused by using Struts tags without the associated filter. Struts tags are only usable when the
    FCKeditor 在JSP上的完全安装
    Java遍历文件夹的2种方法
    充电电池和充电时间说明
    吃知了有什么好处
  • 原文地址:https://www.cnblogs.com/chenting123456789/p/11946139.html
Copyright © 2011-2022 走看看