枚举

简述

顾名思义,枚举便是依次列举出所有可能产生的结果,根据题中的条件对所得的结果进行逐一的判断,过滤掉那些不符合要求的,保留那些符合要求的,也可以称之为暴力算法。

应用场合

在竞赛中,并不是所有问题都可以使用枚举算法来解决(事实上,只有少数),只有当问题的所有解的个数不太多时,并在我们题目中可以接受的时间内得到问题的解,才可以使用枚举。

例题

例题1

题意:输入一个正整数n,按从小到大的顺序输出形如a/b=n的表达式,其中100<=a<=999,2<=n<=79,且b必须是素数。
思路:a和n的范围都很小,我们可以使用枚举,代码如下:

#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;

bool check(int x)
{
    bool flag = true;
    for (int i = 2; i*i <= x; ++i) {
        if (x%i == 0) {
            flag = false;
            break;
        }
    }
    return flag;
}

int main()
{
    int n;
    while (~scanf("%d", &n)) {
        for (int i = 100; i < 1000; ++i) {
            for (int j = 1; j < i; ++j) {
                if (check(j) && i%j == 0 && i/j == n) {
                    printf("%d/%d=%d\n", i, j, n);
                }
            }
        }
    }
    return 0;
}

例题2.hrbust 1565

题意:给出一个数字n(n<=1000000)请你计算出除了1和n之外n的因子数的个数。
要求:Time Limit: 1000 MS , Memory Limit: 10240 K
思路:首先我们通过分析n的范围和时限(1000ms)可以知道这道题可以使用枚举,我们可以通过枚举1到n中的每个整数,并判断该数是否是n的因子,使用一个count变量进行统计,时间复杂度是O(n),代码如下:

int count=0;
for(int i=2;i<n;i++)
    if(n%i==0)
        count++;
printf("%d\n",count);

拓展:此题时限是1000ms,使用O(n)的算法可以过,如果把n的范围改成n<呢,O(n)的算法就会超时,那么应该怎么办?我们考虑这样一个规律:首先我们假设n是16,那么n的因子分别是1,2,4,8,16,我们可以得到这样一个规律:如果a是n的因子,那么n/a一定也是n的因子!所以我们可以将枚举的范围缩小到,这样我们可以把枚举的复杂度降低到O()。

results matching ""

    No results matching ""