算法设计值循环与递归(完数问题,鞍点问题,整数划分,矩阵下三角有规律排列)

完数

问题描述

编算法找出1000以内所有完数
完全数(Perfect number)。如果一个数恰好等于它的真因子之和,则称该数为“完全数” 。各个小于它的约数(真约数,列出某数的约数,去掉该数本身,剩下的就是它的真约数)的和等于它本身的自然数叫做完全数(Perfect number),又称完美数。例如,28的因子为1、2、4、7,14,而28=1+2+4+7+14。因此28是“完数”。编算法找出1000之内的所有完数,并按下面格式输出其因子:28 it’s factors are 1,2,4,7,14。(注意完数的因子不包括它本身)

代码实现

int main()
{
    int i;
    int j;
    int a[1000];
    int s;
    int k;

    for(i=1;i<1000;i++)
    {
        a[1000]={0};
        k=0;
        s=0;
        for(j=1;j<i;j++)
        {
            if(i%j==0)
            {
                a[k]=j;
                k++;
                s=s+j;
            }
        }
        if(s==i)
            {printf("%d it's factors are ",i);
            for(j=0;j<k;j++)
               printf("%d ",a[j]);
            printf("\n");}
    }
}

鞍点

问题描述

求一个矩阵的鞍点 (即在行上最小而在列上最大的点)。

代码实现

#include 

using namespace std;

int main()
{
    int a[10][10];//定义一个二维数组,用来存取矩阵的内容
    int k=1;
    int f;
    int i,j;
    for(i=0;i<5;i++)
        for(j=0;j<5;j++)
    {
        scanf("%d",&a[i][j]);
    }
    int smallest;
    int h;
    int flag=0;
    for(i=0;i<5;i++)
    {
        smallest=66535;
        flag=0;
        for(j=0;j<5;j++)
        {
            if(a[i][j]<smallest)
            {
                smallest=a[i][j];
                f=j;
            }
        }
        printf("%d  ",smallest);
        for(h=0;h<5;h++)
        {
            if(a[h][f]>smallest)
            {
                flag=1;
                break;}
        }
        //printf("%d ",flag);
        if(!flag)
            printf("%d",smallest);
    }
}

下三角有规律输出

题目描述

编写算法:打印具有下面规律的图形。
1
5 2
8 6 3
10 9 7 4

代码实现

int main()
{
    int i;
    int j;
    int a[10][10];
     int k=1;
    for(i=0;i<10;i++)
   {
       for(j=i;j<10;j++)
       {
           a[j][j-i]=k;
           k++;
       }
   }
   for(i=0;i<10;i++)
    {for(j=0;j<=i;j++)
   {
       printf("%3d ",a[i][j]);
   }
   printf("\n");
    }
}

整数的划分问题

问题描述

对于一个正整数n的划分就是把n写成一系列正整数之和的表达式。例如,对于正整数n=6,它可以划分为:
6
5+1
4+2
4+1+1
3+3
3+2+1
3+1+1+1
2+2+2
2+2+1+1
2+1+1+1+1
1+1+1+1+1+1

算法思想

如果{m1,m2,… ,mi}中的最大值不超过m,即max(m1,m2,…,mi) <=m,则称它属于n的一个m划分。这里我们记n的m划分的个数为f(n,m)
根据n和m的关系,考虑以下几种情况:
(1)当n=1时,不论m的值为多少(m>0),只有一种划分即{1};
(2)当m=1时,不论n的值为多少,只有一种划分即n个1,{1,1,1,…,1};
(3)当n=m时,根据划分中是否包含n,可以分为两种情况:
(a)划分中包含n的情况,只有一个即{n};
(b)划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有(n-1)划分。
(4) 当n (5)但n>m时,根据划分中是否包含最大值m,可以分为两种情况:
(a)划分中包含m的情况,即{m, {x1,x2,…xi}}, 其中{x1,x2,… xi} 的和为n-m,因此这情况下为f(n-m,m);
(b)划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分,个数为f(n,m-1);
因此 f(n, m) = f(n-m, m)+f(n,m-1).

代码实现

int c[50];//存储划分
int i;
void  devision( int j,int n, int m)
{
    if(n==1)
    {
        c[j]=1;
        j++;
        printf("%d",c[0]);
        for(i=1;i<j;i++)
            printf("+%d",c[i]);
            printf("\n");
    }
    else if(m==1)
    {
        for(i=0;i<n;i++)
        {
            c[j]=1;
            j++;
        }
        printf("%d",c[0]);
        for(i=1;i<j;i++)
            printf("+%d",c[i]);
            printf("\n");
    }
    else if(n<m)
     devision(j,n,n);
    else if(n==m)
        {
            devision(j,n,n-1);
            c[j]=n;
            j++;
            printf("%d",c[0]);
            for(i=1;i<j;i++)
                printf("+%d",c[i]);
                printf("\n");
            }

    else
        {

             devision(j,n,m-1);
            c[j]=m;
            j++;
            devision(j,n-m,m);
        }

}

你可能感兴趣的:(算法,c语言)