UVa 12377 - Number Coding

题目:一个数可以用一种素数元素的个数表示的形式,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;
}
时间: 2024-10-28 21:58:15

UVa 12377 - Number Coding的相关文章

UVA 1558 - Number Game(博弈dp)

UVA 1558 - Number Game 题目链接 题意:20之内的数字,每次可以选一个数字,然后它的倍数,还有其他已选数的倍数组合的数都不能再选,谁先不能选数谁就输了,问赢的方法 思路:利用dp记忆化去求解,要输出方案就枚举第一步即可,状态转移过程中,选中一个数字,相应的变化写成一个函数,然后就是普通的博弈问题了,必胜态之后必有必败态,必败态之后全是必胜态 代码: #include <stdio.h> #include <string.h> const int N = 105

uva 10706 Number Sequence(找规律)

uva 10706 Number Sequence A single positive integer iis given. Write a program to find the digit located in the position iin the sequence of number groups S1S2-Sk. Each group Skconsists of a sequence of positive integer numbers ranging from 1 to k, w

UVA 11885 - Number of Battlefields(斐波那契)

11885 - Number of Battlefields 题意:给周长,求能围成的战场数目,不包括矩形. 思路:具体的递推没递推出来,但是看了网上一个规律,如果包括矩形的答案应该是斐波那契数列(但是奇数情况为0),然后减去矩形数目就是答案,矩形数目为n / 2 - 1,用矩阵快速幂就能求了. 具体的递推过程哪位大神能指点下... 代码: #include <stdio.h> #include <string.h> const long long MOD = 987654321;

uva 11885 - Number of Battlefields(矩阵快速幂)

题目连接:uva 11885 - Number of Battlefields 题目大意:给出周长p,问多少种形状的周长为p的,并且该图形的最小包围矩阵的周长也是p,不包括矩形. 解题思路:矩阵快速幂,如果包含矩形的话,对应的则是斐波那契数列的偶数项,所以对应减去矩形的个数即可. #include <cstdio> #include <cstring> using namespace std; typedef long long ll; const ll MOD = 9876543

UVA - 10706 Number Sequence

先找到是在哪个集合内,再找到是集合内的哪个元素,最后找到元素的第几位数 #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; long long table[100010]; long long psum[100010]; int n=100000; void maketable() { int i,flag=1,x=0;

UVa 263 - Number Chains

题目:给你一个数字n0,将它的每个位的数字按递增排序生成数a,按递减排序生成数b, 新的数字为n1 = a-b,下次按照同样方法计算n1,知道出现循环,问计算了多少次. 分析:数论.模拟.直接模拟计算即可,利用hash表判重. 说明:注意初始化. #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #inc

UVa 11371 - Number Theory for Newbies

題目:給你一個數字n,將裡面每位的數重新組合形成a,b,使得a-b最大且是9的倍數. 分析:數論.題目要求a,b和n的位數相同,不能有前導0. 定理1:交換一個數字中的某兩個位的數,形成的新數組和原數字之差是9的倍數: 證明1:設數字為abc..i..j...xwz,其中每个字母代表一个位,对应值可以相同, 那么随意交换两位i,j得到的新数字为abc..j..i..xwz,做差为9..90..0 *(i-j), 所以一定是9的倍数,得证. 通過上面定理可以繼續證明,任意交換任意位數字形成的新數字

UVA 1650 Number String

https://vjudge.net/problem/UVA-1650 题意:D表示比前一个数打,I表示比前一个数小,?表示不确定 给出一个长为n由D I?组成的字符串,问满足字符串大小要求的n+1的排列的方案数 SDOI2010地精部落的套路 http://www.cnblogs.com/TheRoadToTheGold/p/7305170.html dp[i][j]前i个数的排列中,第一个为j的方案数 #include<cstdio> #include<cstring> #de

UVa 11064 - Number Theory

题目:求给顶一个数n,的所有的1 ≤ m ≤ n的m,使得gcd(m,n)≠ 1 且 gcd(m,n)≠ m. 分析:数论,素数筛法,欧拉函数. 设pi为n的第i个素数因,k1为第i个素数因子的个数,则有: 1 ≤ m ≤ n,gcd(m,n)= 1 的m的个数为欧拉函数: 欧拉函数:φ(n)= n *(1 - 1/p1)*(1 - 1/p2)*(1 - 1/p3)*-*(1 - 1/pt): 1 ≤ m ≤ n,gcd(m,n)= m 的m的个数为n的所有因数的个数: 因数个数:f(n)= (