UVA 12377 Number Coding --DFS

题意:给一串数字,第一个数是Num的话,要使后面的数字组成Num个数,而且为不降的,将这Num个数分配到9个素因子上作为指数,问能组成多少个不同的数

解法:dfs一遍,看后面的数字能组成Num个不降数字的方法种数,及该种方法的不同数字的个数,然后这些方法加起来。具体见代码吧。

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <string>

#define ll long long

using namespace std;

#define N 30017



int C,Num;

string S;

int c[10] = {1,9,36,84,126,126,84,36,9,1};

int cnt[12];

ll a[12];

int tot,len;

ll Res;



ll fac(int n)

{

    ll res = 1LL;

    for(int i=n;i>=1;i--)

        res *= i;

    return res;

}



void calc()

{

    ll res = fac(Num)*c[Num];

    for(int i=0;i<tot;i++)

        res /= fac(cnt[i]);

    Res += res;

}



void check(int u,int v,int num)

{

    if(num == Num && u == v)

    {

        calc();

        return;

    }

    ll ans = 0;

    if(num == Num)

        return;

    if(S[u] == '0')

        return;

    for(int i=u;i<v;i++)

    {

        ans += 10LL*ans + S[i]-'0';

        if(num == 0 || ans >= a[tot-1])

        {

            if(ans == a[tot-1])  //重复

            {

                cnt[tot-1]++;

                check(i+1,len,num+1);

                cnt[tot-1]--;

            }

            else  //非重复,新建

            {

                cnt[tot]++;

                a[tot++] = ans;

                check(i+1,len,num+1);

                cnt[tot-1]--;

                tot--;

            }

        }

    }

}



int main()

{

    int t,i;

    scanf("%d",&t);

    while(t--)

    {

        cin>>S;

        Num = S[0]-'0';

        len = S.length();

        tot = 0;

        Res = 0;

        check(1,len,0);

        printf("%lld\n",Res);

    }

    return 0;

}
View Code

你可能感兴趣的:(number)