SPOJ_AMR10I_Dividing Stones(DFS)

题型:搜索


题意:

       对N进行整数拆分,每种拆分方法求积得到一个值,问不同的值有多少。

例如

       n=5:

                 1=1*1*1*1*1
                 2=2*1*1*1
                 3=3*1*1
                 4=4*1
                 5=5
                 6=2*3

             ans = 6


分析:

       问不同的积的个数,由于整数又可以用素数之积来表示,所以即使不用素数,最后得出的积也可以由素数之积得出,因此可以用70以内的素数已经搜索,而且整数可以用素数之和来表示,所以dfs时,用选与不选当前这个素数来深搜,若当前的n小于当前的素数值,则return


代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<set>

#define LL long long
using namespace std;

int pri[] = {2 ,3 ,5 ,7 ,11 ,13 ,17 ,19 ,23 ,29 ,31 ,37 ,41 ,43 ,47 ,53 ,59 ,61 ,67 ,71};
///20

int n,p;
set<LL> ans;

void dfs(int pos,int now,LL mul){
    ans.insert(mul);
    if(now < pri[pos]) return;
    ///用pri[pos]
    dfs(pos,now-pri[pos],mul*pri[pos]%p);
    ///不用pri[pos]
    dfs(pos+1,now,mul);
}


int main() {
    int _;
    scanf("%d",&_);
    while(_--){
        scanf("%d%d",&n,&p);
        ans.clear();
        dfs(0,n,1);
        printf("%d\n",ans.size());
    }
    return 0;
}
/**
2 ,3 ,5 ,7 ,11 ,13 ,17 ,19 ,23 ,29 ,31 ,37 ,41 ,43 ,47 ,53 ,59 ,61 ,67 ,71
*/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值