Timus 1013. K-based numbers. Version 3
2008-07-04 19:22
477 查看
Timus 1013. K-based numbers. Version 3 要求计算出不包括相邻的零的 N 位 K-进制数共有多少个。
Memory Limit: 16 MB
Let’s consider K-based numbers, containing exactly N digits. We define a number to be valid if its K-based notation doesn’t contain two successful zeros. For example:
1010230 is a valid 7-digit number;
1000198 is not a valid number;
0001235 is not a 7-digit number, it is a 4-digit number.
Given two numbers N and K, you are to calculate an amount of valid K based numbers, containing N digits.
You may assume that 2 ≤ K ≤ 10; N ≥ 2; N + K ≤ 1800.
解答如下:
1 using System;
2
3 namespace Skyiv.Ben.Timus
4 {
5 // http://acm.timus.ru/problem.aspx?space=1&num=1013
6 sealed class T1013
7 {
8 static void Main()
9 {
int n = int.Parse(Console.ReadLine()), i = 2;
int k = int.Parse(Console.ReadLine()) - 1;
BigInteger m = 0;
for (BigInteger p = 1, q = k; i <= n; i++, p = q, q = m) m = (p + q) * k;
Console.WriteLine(m);
}
}
sealed class BigInteger
{
int[] digits = new int[1800];
public BigInteger(int n)
{
digits[0] = n;
if (digits[0] > 9) Format();
}
public BigInteger(BigInteger x)
{
Array.Copy(x.digits, digits, digits.Length);
}
public static implicit operator BigInteger(int x)
{
return new BigInteger(x);
}
public static BigInteger operator +(BigInteger x, BigInteger y)
{
BigInteger z = new BigInteger(x);
for (int i = x.digits.Length - 1; i >= 0; i--) z.digits[i] = x.digits[i] + y.digits[i];
z.Format();
return z;
}
public static BigInteger operator *(BigInteger x, int y)
{
BigInteger z = new BigInteger(x);
for (int i = x.digits.Length - 1; i >= 0; i--) z.digits[i] = x.digits[i] * y;
z.Format();
return z;
}
void Format()
{
for (int quotient = 0, i = 0; i < digits.Length; i++)
{
int numerator = digits[i] + quotient;
quotient = numerator / 10;
digits[i] = numerator % 10;
}
}
public override string ToString()
{
int n = digits.Length - 1;
while (n >= 0 && digits
== 0) n--;
if (n < 0) return "0";
char[] cs = new char[n + 1];
for (int i = n; i >= 0; i--) cs[i] = (char)(digits[n - i] + '0');
return new string(cs);
}
}
}
这道题要求计算出不包括相邻的零的 N 位 K-进制数共有多少个。这里 2 ≤ K ≤ 10; N ≥ 2; N + K ≤ 1800。
我们还是开始找规律吧。右图是 K = 4,N = 3 的情况。
我们用 Mn 来表示 n 位 K-进制数的数量。从右图中可以看出:
M2 = 12, M3 = 45
经过仔细观察,我们假设:
M0 = 1, M1 = 3
然后再经过认真分析,我们得到以下规律:
M0 = 1, M1 = K - 1, Mn = (K - 1) * (Mn-1 + Mn-2) (n > 1)
在递推公式 Mn = (K - 1) * (Mn-1 + Mn-2) 中:
系数 K - 1 代表 K-进制数的最高位从 1 到 K - 1
Mn-1 代表次高位不为零的情形
Mn-2 表示次高位为零的情形
然后,对于 K = 2、K = 3 在 N 比较小的情况下验证了这个规律。
既然有了递推公式,写出相应的程序自然易如反掌。
但是,要注意,当 K = 10,N = 1790 时,M1790 接近 101790,所以要使用 BigInteger 类来进行计算。
实际上,这个问题共有三姐妹,分别是:
当然,上面的程序也完全适用于 Timus 1009 和 Timus 1012。
另外,对于 Timus 1009,把上面程序 Main() 方法中的第 12 和 13 行中的 BigInteger 改为 int 也完全没有问题。因为 int.MaxValue = 2,147,483,647,而我们有:
从上表中可以看出,Timus 1009 的输出绝对不会大于 1,434,392,064,所以使用 int 是安全的。
下面是这个程序的运行情况:
其中 ID 为 2147015 的记录就是把 BigInteger 改为 int 后的程序的运行结果,运行时间为 0.093 秒。这个结果有点奇怪,因为她比使用 BigInteger 的程序的运行时间 0.078 秒还要大。因为一般来说,用 int 进行运算应该比 BigInteger 快才对。
修改后的程序如下所示:
1 using System;
2
3 namespace Skyiv.Ben.Timus
4 {
5 // http://acm.timus.ru/problem.aspx?space=1&num=1009
6 sealed class T1009
7 {
8 static void Main()
9 {
int m = 0, n = int.Parse(Console.ReadLine());
int k = int.Parse(Console.ReadLine()) - 1;
for (int i = 2, p = 1, q = k; i <= n; i++, p = q, q = m) m = (p + q) * k;
Console.WriteLine(m);
}
}
}
1013. K-based numbers. Version 3
Time Limit: 2.0 secondMemory Limit: 16 MB
Let’s consider K-based numbers, containing exactly N digits. We define a number to be valid if its K-based notation doesn’t contain two successful zeros. For example:
1010230 is a valid 7-digit number;
1000198 is not a valid number;
0001235 is not a 7-digit number, it is a 4-digit number.
Given two numbers N and K, you are to calculate an amount of valid K based numbers, containing N digits.
You may assume that 2 ≤ K ≤ 10; N ≥ 2; N + K ≤ 1800.
Input
The numbers N and K in decimal notation separated by the line break.Output
The result in decimal notation.Sample
input | output |
---|---|
2 10 | 90 |
1 using System;
2
3 namespace Skyiv.Ben.Timus
4 {
5 // http://acm.timus.ru/problem.aspx?space=1&num=1013
6 sealed class T1013
7 {
8 static void Main()
9 {
int n = int.Parse(Console.ReadLine()), i = 2;
int k = int.Parse(Console.ReadLine()) - 1;
BigInteger m = 0;
for (BigInteger p = 1, q = k; i <= n; i++, p = q, q = m) m = (p + q) * k;
Console.WriteLine(m);
}
}
sealed class BigInteger
{
int[] digits = new int[1800];
public BigInteger(int n)
{
digits[0] = n;
if (digits[0] > 9) Format();
}
public BigInteger(BigInteger x)
{
Array.Copy(x.digits, digits, digits.Length);
}
public static implicit operator BigInteger(int x)
{
return new BigInteger(x);
}
public static BigInteger operator +(BigInteger x, BigInteger y)
{
BigInteger z = new BigInteger(x);
for (int i = x.digits.Length - 1; i >= 0; i--) z.digits[i] = x.digits[i] + y.digits[i];
z.Format();
return z;
}
public static BigInteger operator *(BigInteger x, int y)
{
BigInteger z = new BigInteger(x);
for (int i = x.digits.Length - 1; i >= 0; i--) z.digits[i] = x.digits[i] * y;
z.Format();
return z;
}
void Format()
{
for (int quotient = 0, i = 0; i < digits.Length; i++)
{
int numerator = digits[i] + quotient;
quotient = numerator / 10;
digits[i] = numerator % 10;
}
}
public override string ToString()
{
int n = digits.Length - 1;
while (n >= 0 && digits
== 0) n--;
if (n < 0) return "0";
char[] cs = new char[n + 1];
for (int i = n; i >= 0; i--) cs[i] = (char)(digits[n - i] + '0');
return new string(cs);
}
}
}
这道题要求计算出不包括相邻的零的 N 位 K-进制数共有多少个。这里 2 ≤ K ≤ 10; N ≥ 2; N + K ≤ 1800。
我们还是开始找规律吧。右图是 K = 4,N = 3 的情况。
我们用 Mn 来表示 n 位 K-进制数的数量。从右图中可以看出:
M2 = 12, M3 = 45
经过仔细观察,我们假设:
M0 = 1, M1 = 3
然后再经过认真分析,我们得到以下规律:
M0 = 1, M1 = K - 1, Mn = (K - 1) * (Mn-1 + Mn-2) (n > 1)
在递推公式 Mn = (K - 1) * (Mn-1 + Mn-2) 中:
系数 K - 1 代表 K-进制数的最高位从 1 到 K - 1
Mn-1 代表次高位不为零的情形
Mn-2 表示次高位为零的情形
然后,对于 K = 2、K = 3 在 N 比较小的情况下验证了这个规律。
既然有了递推公式,写出相应的程序自然易如反掌。
但是,要注意,当 K = 10,N = 1790 时,M1790 接近 101790,所以要使用 BigInteger 类来进行计算。
实际上,这个问题共有三姐妹,分别是:
1009. K-based numbers | 时间限制:1.0 秒 | 2 ≤ K ≤ 10; N ≥ 2; N + K ≤ 18 |
1012. K-based numbers. Version 2 | 时间限制:1.0 秒 | 2 ≤ K ≤ 10; N ≥ 2; N + K ≤ 180 |
1013. K-based numbers. Version 3 | 时间限制:2.0 秒 | 2 ≤ K ≤ 10; N ≥ 2; N + K ≤ 1800 |
另外,对于 Timus 1009,把上面程序 Main() 方法中的第 12 和 13 行中的 BigInteger 改为 int 也完全没有问题。因为 int.MaxValue = 2,147,483,647,而我们有:
N | K | M |
---|---|---|
16 | 2 | 1,597 |
15 | 3 | 2,781,184 |
14 | 4 | 104,879,772 |
13 | 5 | 661,766,144 |
12 | 6 | 1,413,765,625 |
11 | 7 | 1,434,392,064 |
10 | 8 | 837,677,687 |
9 | 9 | 317,882,368 |
8 | 10 | 85,096,170 |
下面是这个程序的运行情况:
其中 ID 为 2147015 的记录就是把 BigInteger 改为 int 后的程序的运行结果,运行时间为 0.093 秒。这个结果有点奇怪,因为她比使用 BigInteger 的程序的运行时间 0.078 秒还要大。因为一般来说,用 int 进行运算应该比 BigInteger 快才对。
修改后的程序如下所示:
1 using System;
2
3 namespace Skyiv.Ben.Timus
4 {
5 // http://acm.timus.ru/problem.aspx?space=1&num=1009
6 sealed class T1009
7 {
8 static void Main()
9 {
int m = 0, n = int.Parse(Console.ReadLine());
int k = int.Parse(Console.ReadLine()) - 1;
for (int i = 2, p = 1, q = k; i <= n; i++, p = q, q = m) m = (p + q) * k;
Console.WriteLine(m);
}
}
}
相关文章推荐
- Ural(Timus) 1013. K-based Numbers. Version 3
- ural 1013. K-based Numbers. Version 3
- URAL 1013. K-based Numbers. Version 3
- URAL 1013. K-based Numbers. Version 3
- Timus 1012,1013 K-based Numbers. Version 2
- Ural(Timus) 1012. K-based Numbers. Version 2
- ural 1013. K-based Numbers. Version 3(动态规划)
- ural 1012K-based Numbers. Version 2 1013. K-based Numbers. Version 3
- Ural_1013. K-based Numbers. Version 3(dp + 高精度)
- 1013. K-based Numbers. Version 2
- Ural 1012. K-based Numbers. Version 2 &&1013. K-based Numbers. Version 3 DP+高精度
- ural1012 K-based Numbers. Version 2
- URAL 1012. K-based Numbers. Version 2
- ural 1012. K-based Numbers. Version 2
- 【DP && 矩阵快速幂 && 快速乘】URAL - 1013 K-based Numbers. Version 3
- URAL1012. K-based Numbers. Version 2
- K-based Numbers. Version 2
- ural 1012 K-based Numbers. Version 2
- URAL 1012 K-based Numbers. Version 2
- ural 1013 K-based Numbers. Version 3