二分算法和poj1423

1.二分算法

题目描述:输入n(n<100000)个整数,,找出其中两个数,,它们之和等于m(题目确保有解)。

解法1:

用两重循环,枚举所有的取数方法,复杂度是o(n²)

for(int i=0;i<n-1;++i)

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

               if(a[i]+a[j]==m)

                    break;

显然这种方法最容易想到,但是算法复杂度和时间都会超时,在poj根本无法提交。

解法2:

1)对数组先进行排序,复杂度是o(n×logn)

2)在使用二分查找算法,最多查找n-2次,复杂度也是o(n×logn)

所以总的复杂度也是o(n×logn),比解法一少了不少。

解法三:

1)还是将数组排序

2)查找的时候。不用二分,设置2个变量i,j,i的初值是0,j的初值n-1,,看a[I]+a[j],如果大于m,就让j-1,反之,就让i+1,直至找到结果。

这种方法和解2差不多,算法复杂度也是o(n×logn)

综上,每次解题时不可盲目解题,要找到复杂度合适的方法解决题目。

2.poj1423

问题描述:在许多应用中,需要非常大的整数。其中一些应用程序使用密钥来安全传输数据、加密等。在这个问题中,您将得到一个数字,您必须确定该数字的阶乘中的位数。

输入:

输出

 

 

思路:当数字较小时,题目还是可以通过简单的乘法算出,但是当数字越来越大时,就给用到别的方法,这里可以使用斯特林公式,专门用来计算阶乘的位数

代码片段:

#include <iostream>
#include <cmath>
using namespace std;

#define pi 3.1415926535898
typedef long long ll;         定义了一个长整型ll
ll steling(ll n)                    长整型函数steling ,参数n阶乘
{
    return ll(int(log10(sqrt(2.0*pi*m))+m*log10(m/e))+1)+1;

int main()
{
    int n;
    cin>>n;                            行数输入
    while(n--){
        int m;                
        cin>>m;                     输入阶数
        if(m==1)                    如果是一阶
            cout<<1<<endl;     就直接输出1
        else
        cout<<steling(m)<<endl;    2阶以上都用用了斯特林公式的函数套用一下。
    }
    return 0;

这个公式在数学上是这样的:

log10(sqrt(2.0*pi*m))+m*log10(m/e))+1     

将数学公式上下同时取对数,在用代码语言专用符号,就得到了上述公式

这种题目只要知道公式,就能很快解决问题,所以多知道学习掌握这种公式非常重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值