Fork me on GitHub

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
posted @ 2014-07-21 19:36  whatbeg  阅读(251)  评论(0编辑  收藏  举报