POJ 1942 Paths on a Grid 解题报告(double妙用)

6 篇文章 0 订阅

    题目大意:每次可以向上走,向右走。问有多少种走法。

    解题报告:简单来说就是求Cmn。不过注意数据范围,unsigned int,用int会超。

    简单做法就是循环较小的数来求,原来写的代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;

bool vis[200];;

int main()
{
    unsigned m,n;
    while(cin>>m>>n && (m&&n))
    {
        memset(vis,0,sizeof(vis));

        if(n<m)
            swap(n,m);
        unsigned long long ans=1;
        unsigned long long sum=n;
        sum+=m;
        for(unsigned i=1;i<=m;i++)
        {
            ans*=sum;
            sum--;
            for(unsigned k=1;k<=m;k++) if(!vis[k] && ans%k==0)
            {
                ans/=k;
                vis[k]=true;
            }
        }
        printf("%lld\n",ans);
    }
}

    A了之后搜了一下别人的解题报告。不管有没有A,都看一下别人的解题帮,个人习惯,总能学点别的东西,比如这次。我们可以直接用double来存储答案。double共64位,尾数为52位,精度为-2^53到2^53(准确表示整数的范围),不用担心转换成unsigned的精度的。代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <iomanip>
using namespace std;

bool vis[200];

int main()
{
    unsigned m,n;
    while(cin>>m>>n && (m|n))
    {
        double sum=(n+m);
        double mm=m<n?m:n;

        if(mm==0)
        {
            puts("1");
            continue;
        }

        double ans=1;
        do
        {
            ans*=sum/mm;
            sum=sum-1;
            mm=mm-1;
        } while(mm>0);
        cout<<fixed<<setprecision(0)<<ans<<endl;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值