51Nod 2656 阿克曼函數 找規律

1. 題目描述

1.1. Limit

Time Limit: 1000 ms

Memory Limit: 131,072 kB

1.2. Problem Description

阿克曼(Arkmann)函數 A(m,n)A(m, n) 中,m與n的定義域是非負整數且本題中 m3m \le 3n16n\le 16

函數的定義爲:

akm(m,n)={n+1,(m=0)akm(m1,1),(m>0,n=0)akm(m1,akm(m,n1)),(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. }


1.3. Input

兩個整數 mm nn


1.4. Output

一個整數,akm(m,n)akm(m,n)的結果


1.5. Sample Input

1 1

1.6. Sample Output

3

1.7. Source

51Nod 2656 阿克曼函數


2. 解讀

如果直接使用 akm(m,n)akm(m,n) 進行計算,最後一個點會超時。這時考慮到題目所給的數據範圍 0m30 \le m \le 30n160 \le n\le 16 比較小,帶入一些數字嘗試找出 akm(m,n)akm(m,n) 的規律。

mm nn akm(m,n)akm(m,n) mm nn 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 nn n+2n+2 2 nn 2n+32n+3
mm nn akm(m,n)akm(m,n)
3 1 13
3 2 29
3 3 61
3 4 125
3 n 2n+332^{n+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));
}

聯繫郵箱:[email protected]

Github:https://github.com/CurrenWong

歡迎轉載/Star/Fork,有問題歡迎通過郵箱交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章