算法设计与分析习题及解析(一)

循环与递归的应用

求2+22+222+2222+......+222222(n个2)精确计算

(1.循环算法)

#include<stdio.h>

#include<math.h>

int main()

{

    int s=0,sum=0,n,j;

    scanf("%d",&n);

    for(j=0;j<n;j++)

    {

        s=s+pow(10,j)*2;

        sum=sum+s;

    }

    printf("%d",sum);

    return 0;

}

运行结果:

 

(2.递归算法)

#include<stdio.h>

int sum(int n)

{

    if(n>1)

    {

        sum(n)=sum(n-1)*10+2;

        n--;

    }

    else sum(n)=2;

}

int main()

{

    int n,s;

    scanf("%d",&n);

    s+=sum(n);

    printf("%d",s);

    return 0;

}

运行结果:

 

 

编写一个算法,其功能是给一维数组输入任意6个整数,假设为5,7,4,8,9,1,然后建立一个具有如图所示的方阵,并打印出来。

5  7  4  8  9  1

1  5  7  4  8  9

9  1  5  7  4  8

8  9  1  5  7  4

4  8  9  1  5  7

7  4  8  9  1  5

#include<stdio.h>

int main()

{

    int j,i,m,k,a[6];

    for(i=0;i<6;i++)

    scanf("%d",&a[i]);

    for(i=0;i<6;i++)

    printf("%6d",a[i]);

    printf("\n");

    m=k=5;

    for(i=0;i<5;i++)

    {

        for(j=0;j<6;j++)

        {

            printf("%6d",a[k++]);

            if(k>5)k=0;

        }

        k=m;k--;m=k;

        printf("\n");

    }

    return 0;

}

 

趣味矩阵一

编程打印如下的n*n方阵(两种方法)

1   2   3   4   5   6   7 

24  25  26  27  28  29  8

23  40  41  42  43  30  9

22  39  48  49  44  31  10

21  38  47  46  45  32  11

20  37  36  35  34  33  12

19  18  17  16  15  14  13

(方法一)

#include<stdio.h>

int main()

{

    int i,j,a[100][100],n,k=1;

    scanf("%d",&n);

    for(i=1;i<=n/2;i++)

    {

        for(j=i;j<=n-i;j++)//上方

        a[i][j]=k++;

        for(j=i;j<=n-i;j++)//右侧

        a[j][n-i+1]=k++;

        for(j=n-i+1;j>=i+1;j--)//下方

        a[n-i+1][j]=k++;

        for(j=n-i+1;j>=i+1;j--)//左侧

        a[j][i]=k++;     

    }

if(n%2==1)

{i=(n+1)/2;

a[i][i]=n*n;

 }

 for(i=1;i<=n;i++){

 for(j=1;j<=n;j++)

 printf("%6d",a[i][j]);

 printf("\n");

}

 return 0;

}

 

 

方法2:

#include<stdio.h>

int main()

{

    int t,i,j,k,n,a[10][10],b[2],x,y;

    scanf("%d",&n);

    b[0]=0;

    b[1]=1;

    k=n;

    t=1;

    x=1;

    while(x<=n*n){

        for(y=1;y<=2*k-1;y++)

        {

            b[y/(k+1)]=b[y/(k+1)]+t;

            a[b[1]][b[0]]=x;

            x=x+1;

        }

            k=k-1;

            t=-t;

    }

    for(i=1;i<=n;i=i+1)

    {

        printf("\n");

        for(j=1;j<=n;j=j+1)

        printf("%6d",a[i][j]);

    }

    return 0;

}

 

编程打印如下所示的n*n方阵的上三角阵

1  3  6  10  15

2  5  9  14

4  8  13

7  12

11

#include<stdio.h>

int main()

{

   int i,j,k=1,a[10][10],n;

   scanf("%d",&n);

   for(i=1;i<=n;i++)

   {

   for(j=1;j<=i;j++)

   a[i-j+1][j]=k++;

    }

   for(i=1;i<=n;i++)

   {

   printf("\n");

   for(j=1;j<=n-i+1;j++)

   printf("%6d",a[i][j]);

    }

   return 0; 

}

 

趣味矩阵二

编写程序打印形如图所示的n*n方阵

  1. 1  1  1  1  1               1  1  1  1  1
  1. 2  2  2  2  1               1  2  2  2  2
  1. 2  3  3  2  1               1  2  3  2  1
  1. 2  3  3  2  1               1  2  3  2  1
  1. 2  2  2  2  1               1  2  2  2  2

1  1  1  1  1  1               1  1  1  1  1

#include<stdio.h>

   int main(){

      int x,i,j,k=1,n,a[20][20];

      printf("请输入n的值");

      scanf("%d",&n);

      for(x=1;x<=n/2;x++){

         for(i=k;i<n-x+1;i++)//上方

         a[x][i]=k;

         for(j=i,i=x;i<n-x+1;i++)//右侧

         a[i][j]=k;

         for( ;i>k;i--)//下方

         a[j][i]=k;

         for( ;j>k;j--)//左侧

         a[j][i]=k;

         k++;

      }

      for(i=1;i<=n;i++){

      printf("\n");

      for(j=1;j<=n;j++)

      printf("%6d",a[i][j]);

   }

   return 0;

     

   }

  

优化算法的基本技巧一

P115-12

有52张牌,使他们全部正面朝上,第一轮是从第2张开始,凡是2的倍数位置上的牌翻成正面嘲下;第二轮从第3张开始,凡是3的倍数位置上的牌正面朝上的翻成正面朝下,正面朝下的翻成正面朝上;第三轮从第4张牌开始,凡是4的倍数位置上的牌按上面相同规则翻转,以此类推,直到翻得牌超过104张为止。统计最后有几张牌正面朝上,以及他们的位置号。

#include<stdio.h>

int main()

{

   int a[53],i,j=0,k=2;

   for(i=0;i<53;i++)

   a[i]=1;

   while(j<=104){

      for(k=2;k<53;k++){

      for(i=k;i<53;i++){

         if(i%k==0)

         {a[i]=-1*a[i];j++;}

         if(j>104)break;

        }

           if(j>104)break;

     }

   }

   j=0;

   for(i=1;i<53;i++)

   {

      if(a[i]==1)

      {

         printf("%6d",i);

         j++;

      }

     

   }

   printf("有%d张牌正面朝上",j);

  

}

 

P115-(13)

A,B,C,D,E5人为某次竞赛的前五名,他们在名次公布前猜名次。

A说:B得第三名,C得第五名。

B说:D得第二名,E得第四名。

C说:B得第一名,E得第四名。

D说:C得第一名,B得第二名。

E说:D得第二名,A得第三名。

结果每个人都猜对了一半,实际名次是什么呢?

#include<stdio.h>

int main()

{

   int a,b,c,d,e;

   for(a=1;a<=5;a++)

   for(b=1;b<=5;b++)

   if(a!=b)

   for(c=1;c<=5;c++)

   if(c!=a&&c!=b)

   for(d=1;d<=5;d++){

      if(d!=a&&d!=b&&d!=c)

      e=15-a-b-c-d;

      if((b==3||c==5)+(d==2||e==4)+(b==1||e==4)+(e==1||b==2)+(d==2||a==3)==5&&(b==3&&c==5)+(d==2&&e==4)+(b==1&&e==4)+(e==1&&b==2)+(d==2&&a==3)==0)

      {

         printf("a=%d b=%d c=%d d=%d e=%d",a,b,c,d,e);

         break;

      }

   }

return 0; 

}

 

 

 

P116-(15)

两个乒乓球队进行比赛,各出3人.甲队为A,B,C三人,乙队为X,Y,Z,三人,已抽签决定比赛名单。有人向队员打听比赛的名单,A说他不和X比,C说他不和X、Z比,请编写算法找出3对赛手的名单?

#include<stdio.h>

int main()

{

   int a,b,c;

   for(a=1;a<=3;a++)

   for(b=1;b<=3;b++)

   if(a!=b)

   {

      c=6-a-b;

      if(a!=1&&c!=1&&c!=3)

      printf("a=%d b=%d c=%d ",a,b,c);

   }

return 0; 

}

 

 

 

优化算法基本技巧二

P115-(9)有一只经过训练的蜂蜜只能爬向右侧相邻的蜂房,不能反向爬行。如图,试求出蜜蜂从蜂房A爬到蜂房B的可能路线。(0<a<b<100).

 

3

5

  7

 4

  9

  6

 8

11

 10

13

 12

 14

 

 

 

 

 

 

 

 

#include<stdio.h>

int main()

{

       int a,b,i;

       int r[100]={1,1};

       scanf("%d %d",&a,&b);

       for(i=2;i<100;i++)

       r[i]=r[i-1]+r[i-2];

       printf("路线数位%d",r[b-a]);

       return 0;

}

 

P116-(14)编写算法求满足以下条件的3位整数n:它是完全平方数,其中又有两位数字相同,如144,676等。

#include<stdio.h>

int main()

{

       int a,b,c,i;

       for(i=10;i<32;i++){

              a=i*i/100;

              b=i*i/10%10;

              c=i*i%10;

              if(a==b||a==c||b==c)

              printf("%6d",i*i);

       }

       return 0;

}

 

 

P116-(17)完成给“余”猜数的游戏:

心里先想好一个1~100之间的整数x,将它分别除以3,4和7并得到三个余数,把这三个余数输入计算机,计算机能马上猜出这个数。

please think of a number between 1 and 100

your number divided by 3 has a remainder of 1

your number divided by 4 has a remainder of 0

your number divided by 7 has a remainder of 5

let me think a moment...

your number was 40

分析:由算法书中根据数学建模道理推出,d=28a+21b+36c;

其中,a的系数28是4和7的公倍数且被3整除余1

b的系数21是3和7的公倍数,且被4整出余1

c的系数36是3和4的公倍数,且被7整除余1

代码如下:

#include<stdio.h>

int main()

{

       int a,b,c,d;

       printf("please think of a number between 1 and 100\n");

       printf("your number divided by 3 has a remainder of");

       scanf("%d",&a);

       printf("your number divided by 4 has a remainder of");

       scanf("%d",&b);

       printf("your number divided by 7 has a remainder of");

       scanf("%d",&c);

       printf("let me think a moment...");

       d=28*a+21*b+36*c;

       while(d>84)//3*4*7=84

       d=d-84;

       printf("your number was%d ",d);

       return 0;

}

 

迭代蛮力法的应用:

P185--(2)猴子吃桃子问题,猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了2个,第二天早上又将剩下的桃子吃了一半,又多吃了两个,以后每天早上都吃了前一天剩下的一半零两个,到第10天早上想在吃时,就只剩下两个了。问第一天猴子摘下来多少个桃子?

 #include<stdio.h>

 int main()

 {

      int i,a=2;

       for(i=9;i>=1;i--)

       a=(a+2)*2;

       printf("%d",a);

       return 0;

 }

 

 

P126--(例题5)

一辆吉普车穿越1000千米的沙漠吉普车的总装油量为500加伦,耗油率为1加伦/KM。由于沙漠中没有油库,必须先用这辆车在沙漠中建立临时油库。若吉普车用最少的耗油量穿越沙漠,应在那些地方建立油库,以及各处存储的油量。

#include<stdio.h>

int main()

{

       int dis,k,oil;//dis:距终点的距离,1000-dis:距原点的距离 ,oil:储油量,k:往返次数

       dis=500;k=1;oil=500;

       do{

              printf("storepoint%ddistance%doilquantity%d\n",k,1000-dis,oil);

              k=k+1;

              dis=dis+500/(2*k-1);

              oil=500*k;

       }

       while(dis<1000);

       oil=500*(k-1)+(1000-dis)*(2*k-1);

       printf("storepoint%ddistance%doilquantity%d",k,0,oil);

       return 0;

}

 

P186--(7)

有一堆棋子,两枚两枚的数,最后余一枚;3枚3枚的数,最后余2枚;5枚5枚的数,最后余4枚;6枚6枚的数,最后余5枚;只有7枚7枚的数,最后正好数完,编程求出这堆棋子最少有多少枚棋子。

#include<stdio.h>

int main()

{

       int i,j;

       for(i=1; ;i++){

       j=7*i;

       if(j%2==1&&j%3==2&&j%5==4&&j%6==5)

       break;

   }

   printf("%d",j);

   return 0;

}

 

 

 

  • 6
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值