文章目录
1. 题目描述
1.1. Limit
Time Limit: 1000 ms
Memory Limit: 131,072 kB
1.2. Problem Description
阿克曼(Arkmann)函数 A ( m , n ) A(m, n) A(m,n) 中,m与n的定义域是非负整数且本题中 m ≤ 3 m \le 3 m≤3, n ≤ 16 n\le 16 n≤16。
函数的定义为:
a k m ( m , n ) = { n + 1 , ( m = 0 ) a k m ( m − 1 , 1 ) , ( m > 0 , n = 0 ) a k m ( m − 1 , a k m ( m , n − 1 ) ) , ( m > 0 , n > 0 ) akm(m, n) = {\left\{ \begin{aligned} n+1 & , (m = 0)& \\ akm(m - 1, 1) & , (m > 0, n = 0)& \\ akm(m - 1, akm(m, n - 1)) & , (m > 0, n > 0)& \\ \end{aligned}\right. } akm(m,n)=⎩⎪⎨⎪⎧n+1akm(m−1,1)akm(m−1,akm(m,n−1)),(m=0),(m>0,n=0),(m>0,n>0)
1.3. Input
两个整数 m m m n n n
1.4. Output
一个整数, a k m ( m , n ) akm(m,n) akm(m,n)的结果
1.5. Sample Input
1 1
1.6. Sample Output
3
1.7. Source
2. 解读
如果直接使用 a k m ( m , n ) akm(m,n) akm(m,n) 进行计算,最后一个点会超时。这时考虑到题目所给的数据范围 0 ≤ m ≤ 3 0 \le m \le 3 0≤m≤3, 0 ≤ n ≤ 16 0 \le n\le 16 0≤n≤16 比较小,带入一些数字尝试找出 a k m ( m , n ) akm(m,n) akm(m,n) 的规律。
m m m | n n n | a k m ( m , n ) akm(m,n) akm(m,n) | m m m | n n n | a k m ( m , n ) akm(m,n) akm(m,n) |
---|---|---|---|---|---|
1 | 1 | 3 | 2 | 1 | 5 |
1 | 2 | 4 | 2 | 2 | 7 |
1 | 3 | 5 | 2 | 3 | 9 |
1 | n n n | n + 2 n+2 n+2 | 2 | n n n | 2 n + 3 2n+3 2n+3 |
m m m | n n n | a k m ( m , n ) akm(m,n) akm(m,n) |
---|---|---|
3 | 1 | 13 |
3 | 2 | 29 |
3 | 3 | 61 |
3 | 4 | 125 |
3 | n | 2 n + 3 − 3 2^{n+3} - 3 2n+3−3 |
再将找出的规律写成一个函数进行计算即可。
3. 代码
#include <algorithm>
#include <iostream>
#include <math.h>
#include <string.h>
using namespace std;
int akm(int m, int n)
{
if (m == 0) {
return n + 1;
} else if (m > 0 && n == 0) {
return akm(m - 1, 1);
} else if (m > 0 && n > 0) {
return akm(m - 1, akm(m, n - 1));
} else {
return 0;
}
}
long long calculate(int m, int n)
{
if (m == 0) {
return n + 1;
} else if (m == 1) {
return n + 2;
} else if (m == 2) {
return 2 * n + 3;
} else if (m == 3) {
return pow(2, n + 3) - 3;
} else {
return 0;
}
}
int main()
{
// test case
int m, n;
scanf("%d %d", &m, &n);
// 计算
printf("%lld", calculate(m, n));
}
联系邮箱:curren_wong@163.com
Github:https://github.com/CurrenWong
欢迎转载/Star/Fork,有问题欢迎通过邮箱交流。