UVa 12377 - Number Coding

来源:互联网 发布:apache怎么读 编辑:程序博客网 时间:2024/04/20 02:13

题目:一个数可以用一种素数元素的个数表示的形式,43560=23×32×51×112表示成41223;

            第一个数是素因子的种类,第二个是每个素因子的个数递增排列;给你一个这种形式的串,

            问原来的数可能有几种情况。

分析:数论,计数原理,组合数学。

            对于每个串,第一个数字一定是素因子的种类数;

            首先,利用搜索找到所有剩余串的可能组合形式;

            然后,求出每种情况下的组合数,加和即可。

说明:注意一个新的数字不能以0开始。

#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>using namespace std;int  p[11],f[11];char buf[22];long long value(int s, int t){long long V = 0LL;for (int i = s ; i <= t ; ++ i) {V *= 10LL;V += buf[i]-'0';}return V;}long long save[11];long long temp[11];long long dfs(int s, int l, int d, int n){long long sum = 0LL;if (d == n && s == l) {sum = 0LL+p[n];//去掉相同元素的内部排列 int count = 1;for (int i = 1 ; i < d ; ++ i) {if (save[i] == save[i-1])count ++;else {sum /= f[count];count = 1;}}sum /= f[count];}for (int i = s ; i < l ; ++ i) {save[d] = value(s, i);if ((!d || save[d] >= save[d-1]) && buf[i+1] != '0') {temp[d] = save[d];sum += dfs(i+1, l, d+1, n);save[d] = temp[d];}}return sum;}int main(){p[0] = 1; f[0] = 1;for (int i = 1 ; i < 10 ; ++ i) {p[i] = p[i-1]*(10-i);f[i] = f[i-1]*i;}int n,l,d;while (~scanf("%d",&n)) for (int i = 1 ; i <= n ; ++ i) {scanf("%s",buf);l = strlen(buf);cout << dfs(1, l, 0, buf[0]-'0') << endl;}return 0;}


0 0
原创粉丝点击