C语言-枚举问题

枚举是根据所提出的内容,一一列出该问题的所有可能的解,并在逐一列出的过程中,检验每个可能解是否是问题的真正解,不满足就继续判断下一个。

可以用枚举法解决的问题有以下特点:1.枚举范围是有穷的。2.检验条件确定。

例一:输出正整数n的因数

枚举范围[1,n]

枚举条件:n%i==0

输入:35 输出:1 5 7 35

#include <stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
     if(n%i==0)
        {printf("%d ",i);}
       }
       return 0;
}


👀如果输出的是1,5,7,35 应该怎么修改呢?

并不能直接printf(",%d",i);直接在%d前后加上逗号

所以要么把1拿出来单独考虑,要么把35拿出来单独考虑

printf("%d",1);
    for(int i=2;i<=n;i++)
    {    
     if(n%i==0)
        {printf(",%d",i);}

或者

for(i=1;i<n;i++)
    {    
     if(n%i==0)
        {printf("%d,",i);}
    }
   printf("%d",n);
      

例二:统计正整数因数的个数

非常简单 多引入一个s,修改一下就ok了

#include <stdio.h>
int main()
{
    int n;
    int s= 0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
     if(n%i==0)
        {s=s+1;}
    }    
        printf("%d",s);
       
       return 0;
}

素数(质数)

一个大于1的自然数,除了1和它本身不能被其他自然数整除的数。

素数的判断方法😐❓

1:定义法:统计整数n因数个数,如果恰好为2,则是素数。

2:试除法:枚举[2,n)的每个数i,判断i是否能整除n

定义法(只要在例二的基础上 再加一个if判断就可以了

#include <stdio.h>
int main()
{
    int n;
    int s= 0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
     if(n%i==0)
        {s=s+1;}
    }    
    if(s==2){
         printf("%d是素数",n);
    }
       
       else{
           printf("%d不是素数",n);
       }
       return 0;
}

试除法

#include <stdio.h>
int main()
{
    int n,i;
    int f=1;//假设n为素数
    scanf("%d",&n);
    for(i=2;i<n;i++)
    {if(n%i==0)
     f = 0;//可以整除 
     break;
     }
     if(f==1) {
         printf("yes");}
     else     {
         printf("no");}
       
    return 0;
}

一个一个试的话当输入的数字比较大时速度较慢慢,如何优化呢?😕

6=1*6=2*3

12=1*12=2*6=3*4 因数成对出现 只枚举小的因数即可减少循环次数

循环到平方根即可

#include <stdio.h>
int main()
{
    int n,i;
    int f=1;//假设n为素数
    scanf("%d",&n);
    for(i=2;i<=n/i;i++)
    //或改为i*i<=n(但是当i的数目比较大时i*i可能会爆掉
    //或i<=sqrt(n)()但是要引入数学库函数
    {if(n%i==0)
     f = 0;//可以整除 
     break;
     }
     if(f==1&&n>1) //1的情况要单独考虑且上一步i赋值不能赋为1 不然1就终止循环了
      {
         printf("yes");}
     else     {
         printf("no");}
       
    return 0;
} 

完美数

所有真因子(除了自身以外的约数)的和,恰好等于它本身。

6=1+2+3

6=1+2+4+7+14

#include <stdio.h>
int main()
{
    int n;
    int s= 0;
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        if(n%i==0)
        {
            s=s+i;
        }   
        
    }
    if(s==n)
    {
        printf("yes");
    }
    else
    {
        printf("no");
    }
return 0;
}

最大公约数

定义法

#include <stdio.h>
int main()
{
    int a,b,t;
    scanf("%d %d",&a,&b);
    //a和b的大小不确定 先把a,b大小判断出来
    if(a>b)
    {
        t=a;b=t;a=b;
    }
    
    //for(int i=1;i<=a;i++)不能这样写 比如4和8 i增加到2时就已经成立了
    for(int i=a;i>0;i--)//i要大于0 才能满足比如两个数均是质数时最大公因数为1的情况
    
    {
        if(a%i==0&&b%i==0)
        {
            printf("%d",i);
            break;//这里一定要加break 不然循环不终止 i减小到下一个公约数又会输出
        }
    
    }
    return 0;
}

辗转相除法(欧几里得算法)

最小公倍数

计算A/B+C/D

输入A、B、C、D四个整数(0≤A<10000,0<B<10000,0≤C<10000,0<D<10000)

计算,要求计算结果为最简分式(分子、分母均为非负整数)

输入: 1 2 1 3

输出 :5 6

//计算A/B+C/D
#include <stdio.h>
int main()
{
    int A,B,C,D;
    scanf("%d %d %d %d",&A,&B,&C,&D);
    int x = B*D;//分母
    int y = A*D+B*C;//分子
    
    int n;
        if(x>y)
        {n=x;}
        else
        {n=y;}
        // 用这个更简单 n = x > y ? x : y;
        
        //这一步是为了判断分子和分母的大小
        //后面化简的时候同时除以的数不能比大数大
        
        
    
    for(int i=1;i<n;i++)//  (1)
    {
        
        if(x%i==0&&y%i==0)
        {
               x=x/i;y=y/i;//同时除以公约数化简
            i=1;//返回到(1)的位置执行i++ 也就是从(1+1)2继续 比如12/18除一次2之后还可以再除一次2 而只用i++只能往上 
            
        }
        
    }
    printf("%d %d ",y,x);
    return 0;
    
}

将正整数N分解为素数因子的连乘式

输入:6

输出:2*3

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值