弱校胡策 复式八卦阵

题目描述
刘备请来了“千古人龙”诸葛亮,而最近诸葛亮又在八卦阵的基础扩展出了复式八卦阵,可以在考试开封前30min知道考试的内容。叠加规则如下:首先有一个能量值为 n 的母盘(不占高度),母盘上可放置一个能量值为a1且能量值不超过 n/k 的八卦阵,在八卦阵a1上又可放置一个能量值为 a2且不超过 a1/k的八卦阵,其中k为刘备的幸运数字,很显然能量值不能为负,且为了保证作弊效果最好,会在无法进一步扩展时才会停止,即最上方的八卦阵上无法叠加任何八卦阵时才记做一个完整的复式八卦阵,有了诸葛亮的帮助,刘备一定可以考取满分,但汉献帝刘协不甘如此,但手下无可用之才于是找到了会编程的你,让你算出诸葛亮所办八卦阵的数量对p取模的值以及最高的复式八卦阵的层数,因为这个值可以干扰复式八卦阵的运行。无奈诸葛亮的复式八卦阵可以算出自己的八卦阵是否被算出,若发现自己的复式八卦阵被算出则会更换母盘,并改变刘备的气运即改变刘备的幸运数字 k ,但由于诸葛亮过于自信,他只会对自己的复式八卦阵有没有被算出占卜T次(即会有T组数据)。
输入描述
输入数据的第一行包含两个正整数T、 p, T、 p的意义如题目所述。
后面跟着T组数据,每组数据仅一行,包含了一个正整数n和k,意义如题目所述
输出描述
输出数据一共n行,每行两个整数,表示答案对p取模后的值。
样例输入
2 2
6 2
20 3
样例输出
1 1
1 1
数据范围 对于10%的数据 : p = 2
对于100%的数据 :T<= 20,n <= 10^10, p <= 10的9次方 , k <= 10的6次方。

题目来源:http://codevs.cn/problem/5251/

60分:暴搜

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
typedef long long ll;
ll h,ans,t,p;
void dfs(ll n,ll k,ll gd)
{
    ll sta=n/k;
    if(sta==0)
    {
        ans++;
        h=max(h,gd);
        h%=p;
        ans%=p;
        return;
    }
    for(ll i=n/k;i>=1;i--)
        dfs(i,k,gd+1);
}
int main()
{
    scanf("%lld%lld",&t,&p);
    for(ll i=1;i<=t;i++)
    {
        ll n,k;
        h=0,ans=0;
        scanf("%lld%lld",&n,&k);
        dfs(n,k,0);
        printf("%lld %lld\n",ans,h+1);
    }
    return 0;
}

100分:求一个前缀和递推,用数组sum[i]表示以不大于i为底的母盘所达到的高度之和。用f[i]表示以某一母盘为底的方案数。由题意可知,而f[i]恰好为s[i/k]。所以方程式为:s[i] = s[i – 1] + f[i];

#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
const int maxn=2000005;
ll sum[maxn],f[maxn];
int main()
{
    ll t,p;
    scanf("%lld%lld",&t,&p);
    for(int a=1;a<=t;a++)
    {
        ll n,k,cnt=0,n1;
        sum[1]=sum[0]=f[1]=1;
        scanf("%lld%lld",&n,&k);
        n1=n;
        for(int i=2;i<=n/k;i++)
            f[i]=sum[i/k],sum[i]=(sum[i-1]+f[i])%p;
        while(n1)
        {
            n1/=k;
            cnt++;
        }
        printf("%lld %lld\n",sum[n/k],cnt%p);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值