noip数据结构与算法 之 基础小算法 枚举算法及其延伸思维

noip数据结构与算法 之 基础小算法 枚举算法及其延伸思维

在noip乃至程序开发过程中,枚举算法是一种最常见,最基本,最简单的算法。它很符合我们思考问题的传统方式,易于我们理解,同时也很容易用代码来实现。

枚举的问题一般都很简单,以接下来的问题为例:

问题描述:

给定一个上界n,输出从0~n之间所有自然数是3的倍数的数。

输入数据:

只有一行n。

输出数据:

0~n之间所有3的倍数,以空格隔开。

输入样例:

10

输出样例:

3 6 9

数据范围:

输入数据保证3<n<=100000。

这道题有一个非常简单的思路,我只需要从i=3,4,5,6,7……n这么遍历一遍,然后用i%3==0来判断是不是3的倍数。总体来说不过几行代码。这就是枚举算法的思路,具体代码如下:

#include <iostream>
using namespace std;

int n;

int main(){
    cin>>n;
    for(int i=3;i<=n;++i){
        if(i%3==0){
            cout<<i<<” ”;
        }
    }
    return 0;
}

什么?!这么简单就结束了嘛!?这次讲的东西也太水了吧!不!重要的还在后面呢!假设说还是同样的问题,这时候我的n的取值范围不再是100000这么小了,而是1000000000这么大!这可怎么办呀,我从3列到1000000000要这么多次运算,肯定会超时的呀。

这时候我们换一个思维方式,同样是枚举的算法,这次我开始列数。我知道3是3的倍数,我也知道3+3一定也是3的倍数,它是6。那我就一直+3+3+3…..直到+3完了之后超过1000000000时停止输出,我不就得到了3到1000000000里所有的3的倍数了嘛?这样的话操作次数是原来的1/3,而且省去了%运算,怎么想都比之前的枚举算法更高效嘛。这个算法代码如下:

#include <iostream>
using namespace std;

int n;

int main(){
    cin>>n;
    for(i=3;i<=n;i+=3){
        cout<<i<<” ”;
    }
    return 0;
}

当然接下来我们还能再改,我现在给定l,r,输出从l到r区间内所有3的倍数。其实想起来很简单,就在刚刚的+3算法基础上做一个判断,判断l是不是3的倍数,如果不是找到比l大的最小的一个3的倍数。从它开始+3+3+3+3……边+3边输出。代码实现如下:

#include <iostream>
using namespace std;

int l,r;

int main(){
    cin>>l>>r;
    while(l%3){
        ++l;
    }
    for(i=l;i<=r;i+=3){
        cout<<i<<” ”;
    }
    return 0;
}

以上是关于枚举算法及其延伸思维的介绍。具体再往下可以有很多很多例题,但是我不再举例。枚举的思维很简单,有的也很巧妙。我更想表达的是,在学习noip的过程中,我们更应该保持自己的活跃思维,不断的思考开发新的实现方式,而不是对已有算法或者给定算法形成定式思维。处于活跃状态下我们才能更深入的理解算法,甚至去开发新算法。这种活跃思维在noip的学习路上是必不可少的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值