2019年华南理工大学程序设计竞赛(春季赛) A NB群友

周末打比赛自闭了orz
这题 队友想的是用8重循环暴力 当时卡模拟题就没写…但是感觉不大行
看了个大佬的代码 NB就完事了…还是自己太菜了
举个例子 1 10 变成 ans + ans(1,5)+ ans ( 1 2)+ans(1 1);//以此类推
举个例子 9 10 变成 ans = ans(5,5)= ans ( 3 2)= 0 ;ans = ans (3,3)//以此类推

// 如有错误欢迎大家指正
// 一起学习啊

#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
typedef long long LL;
struct qwe {                                     //可以用pair替代但是我不会
    LL a,b;
    bool operator<(const qwe d)const
    {
        if(a==d.a)
            return b<d.b;
        return a<d.a;
    }
    qwe(LL d1,LL d2)
    {
        a=d1;
        b=d2;
    }
};
map<qwe,LL>m;    //类似记忆化搜索用来存结果
LL dfs(LL l,LL r)
{
    if(l>r||r<=1)//就是如果分不下去了就停止
        return 0;
    qwe tmp(l,r);
    if(m.count(tmp)!=0)
    {
        return m[tmp];
    }
    LL ans=0;
    for(LL i=2;i<=9;i++)
    {
        LL L=ceil(l*1.0/i);// ceil向上取整 必大于等于1
        LL R=r/i;
        if(L<=1&&R>=1)// 这个地方的L小于等于 1 是因为如果L结果为1 那么从上面到现在这个数已经在l r 的区间范围内
            ans++;			// R>=1 代表 除完 的结果 在 R的范围内
        ans+=dfs(L,R);
        ans%=mod;
    }
    return m[tmp]=ans;
}
int main()
{
    LL t,a,b;
    scanf("%lld",&t);
    while(t--)
    {
        scanf("%lld%lld",&a,&b);
        printf("%lld\n",dfs(a,b));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值