[アルゴリズムの設計と分析(クラス後の回答)]再帰

1.n次のスパイラル行列問題を解きます

【問題点の説明】n次のスパイラル行列を作成して出力します。

[入力の説明]入力には複数のテストケースが含まれ、各テストケースは行であり、正の整数n(1≤n≤50)が含まれ、0を入力して終了を示します。
[出力の説明]各テストケースはn行を出力し、各行にはn個の整数が含まれ、整数はスペースで区切られます。

【入力サンプル】4
【出力サンプル】
         12 3 4 12 13 14 5
         11 16 15 6
         10 9 8 7

public class Solution1 {
    
    
	/**
     * 目前已知最优雅的写法
     * Left-Right-Top-Down螺旋模板
     */	
    public int[][] CreateSpiral(int n) {
    
    
        int[][] res = new int[n][n];

        int L = 0;
        int R = n - 1;
        int T = 0;
        int D = n - 1;

        int index = 1;
        int remain = n * n;
        while (remain > 0) {
    
    
            for (int i = L; i <= R && remain > 0; i++) {
    
    
                res[T][i] = (index++);
                remain--;
            }
            T++;
            for (int i = T; i <= D && remain > 0; i++) {
    
    
                res[i][R] = (index++);
                remain--;
            }
            R--;
            for (int i = R; i >= L && remain > 0 ; i--) {
    
    
                res[D][i] = (index++);
                remain--;
            }
            D--;
            for (int i = D; i >= T && remain > 0; i--) {
    
    
                res[i][L] = (index++);
                remain--;
            }
            L++;
        }
        return res;
    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        while (true) {
    
    
            int n = sc.nextInt();
            if (n == 0) {
    
    
                break;
            }
            int[][] res = new Solution1().CreateSpiral(n);
            for (int i = 0; i < n; i++) {
    
    
                for (int j = 0; j < n; j++) {
    
    
                    System.out.print(res[i][j] + " ");
                }
                System.out.println();
            }
        }
    }
}

 


2.ラッキーナンバーの問題を解く

[問題の説明]さまざまなベースを学んだ後、シャオミンはいくつかの数字を拾い上げてゲームを開始しました。Xiao Mingは、日常生活では10進数を最も頻繁に使用し、コンピューターでは2進数も非常に一般的に使用されることを知っています。ここで、数値xに対して、Xiao Mingは2つの関数f(x)とg(x)を定義しました。f(x)は、数値xが10進数で書き込まれた後の各桁の桁の合計を表します。たとえば、f(123)= 1 + 2 + 3 = 6です。g(x)は、数値xが2進数で書き込まれた後の各桁の数値の合計を表します。たとえば、123のバイナリ表現は1111011であり、g(123)= 1 + 1 + 1 + 1 + 0 + 1 + 1 = 6です。Xiao Mingは、いくつかの正の整数についてxがf(x)= g(x)を満たすことを発見し、そのような数をラッキーナンバーと呼びました。今度は、n以下のラッキーナンバーがいくつあるか知りたいですか?

【説明を入力】n(n≤100000)。
【入力内容】n以下のラッキーナンバーの数。
【入力サンプル】21
【入力サンプル】3

public class Solution2 {
    
    
	/**
     * 每一个数都判断是否是LuckyNumber即可,非常简单~
     */	
    public int getLuckyNumber(int n) {
    
    
        int cnt = 0;
        for (int i = 1; i <= n; i++) {
    
    
            cnt += (f(i) == g(i) ? 1 : 0);
        }
        return cnt;
    }

    private int f(int n) {
    
    
        if (n < 10) {
    
    
            return n;
        }
        return n % 10 + f(n / 10);
    }

    private int g(int n) {
    
    
        if (n < 2) {
    
    
            return n;
        }
        return  n & 1 + g(n >> 1);
        // 位运算永远的神
    }


    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        System.out.println(new Solution2().getLuckyNumber(n));
    }
}

 


3.回文配列の問題を解決します

【問題点の説明】デジタルシーケンスが反転後の元のシーケンスと同じである場合、そのようなデジタルシーケンスはパリンドロームシーケンスと呼ばれます。たとえば、{1,2,1}、{15,78,78,15}、{11,2,11}は回文配列であり、{1,2,2}、{15,78,87,51}は、{112,2,11}は回文配列ではありません。次に、数値のシーケンスを指定して、変換操作を許可します。隣接する2つの数値を選択し、シーケンスからこれら2つの数値を削除して、これら2つの数値の合計を2つの前の位置に挿入します(1つとのみを挿入します)。特定のシーケンスをパリンドロームシーケンスに変換するために必要な操作の最小数を見つけます。

[入力の説明]:入力は2行、最初の行はシーケンスの長さn(1≤n≤50)、2番目の行はシーケンス内のn個の整数item [i](1≤item[i]≤1000)です。 、スペースを区切って。
【出力内容】:最小変換回数を示す数値を出力します。

【入力サンプル】41
         1 13
【出力サンプル】2

public class Solution3 {
    
    
	/**
     * 每次计算最外面的一层,递归内层
     */
    public int trans2palindrome(int[] arr, int L, int R) {
    
    
        if (L >= R) {
    
    
            return 0;
        }
        int res = 0;
        int sumL = arr[L++];
        int sumR = arr[R--];
        while (L <= R) {
    
    
            if (sumL < sumR) {
    
    
                sumL += arr[L++];
                res++;
            } else if (sumL > sumR) {
    
    
                sumR += arr[R--];
                res++;
            } else {
    
    
                break;
            }
        }
        return res + trans2palindrome(arr, L, R);
    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int len = sc.nextInt();
        int[] arr = new int[len];
        for (int i = 0; i < len; i++) {
    
    
            arr[i] = sc.nextInt();
        }
        System.out.println(new Solution3().trans2palindrome(arr, 0, len -1));
    }
}

 


4.サイコロゲームの問題を解決します

【問題点】サイコロの数に応じて歩数を決める、つまりサイコロが1の場合は1歩、2の場合は2歩、n歩の場合は歩数を決める。数がnのときに取ることができます。n番目のステップ(n≤サイコロの最大数とサイコロを振る唯一の方法)、合計でサイコロを振る方法の数に到達するようにプレーヤーに依頼します。

[入力の説明]:入力には整数n(1≤n≤6)が含まれます。
[出力の説明]:整数を出力します。これは、サイコロを振る方法の数を意味します。

【入力サンプル】:6
【出力サンプル】:32

public class Solution4 {
    
    
	/**
     * 回溯的最简单最初始版本———不需要记录路径,仅需要记录个数
     */
    public int ThrowDice(int n) {
    
    
        return traceBack(n);
    }

    private int traceBack(int remain) {
    
    
        if (remain == 0) {
    
    
            return 1;
        }
        int sum = 0;
        for (int i = 1; i <= 6 && i <= remain; i++) {
    
    
            sum += traceBack(remain - i);
        }
        return sum;
    }

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        System.out.println(new Solution4().ThrowDice(n));
    }
}

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

⭐️これは、ネットワーク全体で最も美しいJavaソリューションである必要があります> _ <

おすすめ

転載: blog.csdn.net/m0_46202073/article/details/114996082