算法——分治法讲解

分治法

分治法是一个很有趣的算法方法。
分治法的思想很简单,就是将问题分成多个规模大小一样的子问题。这种做法是出自一种平衡子问题的启发思想。
然后这么多个规模大小一样的子问题就可以通过递归进行求解。下面举个小例子:

例如:现在要求3的4次幂。
蛮力法的思想:3*3*3*3
分治法的思想:
这里写图片描述

可能说起来比较抽象。我下面给出几个例子的代码,通过观察你就会慢慢知道分治法的思想核心和使用它了。

数字旋转方阵

效果图:
这里写图片描述

说明:
这里主要将方阵的四周分成四个区域:A区域、B区域、C区域、D区域。然后里面每一层都是一样的子问题。就可以采用递归输出结果了。

代码:

import java.util.Scanner;

/**
 * 分治法——数字旋转方正算法
 * 
 * @author chenjunxu
 * @since 2016-1-20
 */
public class Main {
    /** 用于记录输出的数字 */
    private static int number = 1;

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        scan.close();
        // 创建二维数组(方阵)
        int arr[][] = new int[n][n];
        // 调用方阵递归方法
        huizhuang(0, n, arr, n);
        // 输出二维数组(方阵)
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
    }

    public static void huizhuang(int begin, int size, int arr[][], int n) {
        // 如果方阵的长度等于0,则停止递归(递归出口)
        if (size == 0) {
            return;
        }
        // 如果方阵的长度等于1,则将该数字输出并结束递归(递归出口)
        if (size == 1) {
            arr[begin][begin] = number++;
            return;
        }

        // A区域代码输出
        for (int i = begin; i < n - 1; i++) {
            arr[i][begin] = number++;
        }

        // B区域代码输出
        for (int i = begin; i < n - 1; i++) {
            arr[n - 1][i] = number++;
        }

        // C区域代码输出
        for (int i = n - 1; i > begin; i--) {
            arr[i][n - 1] = number++;
        }

        // D区域代码输出
        for (int i = n - 1; i > begin; i--) {
            arr[begin][i] = number++;
        }

        // 进行递归
        huizhuang(begin + 1, size - 2, arr, n - 1);
    }
}

如果一次看不懂,就慢慢专研,学会怎么做。然后,自己动手做一下,你就会知道其中的道理了。~(>.<)~加油~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
L型组件填图问题 1.问题描述 设B是一个n×n棋盘,n=2k,(k=1,2,3,…)。用分治法设计一个算法,使得:用若干个L型条块可以覆盖住B的除一个特殊方格外的所有方格。其中,一个L型条块可以覆盖3个方格。且任意两个L型条块不能重叠覆盖棋盘。 例如:如果n=2,则存在4个方格,其中,除一个方格外,其余3个方格可被一L型条块覆盖;当n=4时,则存在16个方格,其中,除一个方格外,其余15个方格被5个L型条块覆盖。 2. 具体要求 输入一个正整数n,表示棋盘的大小是n*n的。输出一个被L型条块覆盖的n*n棋盘。该棋盘除一个方格外,其余各方格都被L型条块覆盖住。为区别出各个方格是被哪个L型条块所覆盖,每个L型条块用不同的数字或颜色、标记表示。 3. 测试数据(仅作为参考) 输入:8 输出:A 2 3 3 7 7 8 8 2 2 1 3 7 6 6 8 4 1 1 5 9 9 6 10 4 4 5 5 0 9 10 10 12 12 13 0 0 17 18 18 12 11 13 13 17 17 16 18 14 11 11 15 19 16 16 20 14 14 15 15 19 19 20 20 4. 设计与实现的提示 对2k×2k的棋盘可以划分成若干块,每块棋盘是原棋盘的子棋盘或者可以转化成原棋盘的子棋盘。 注意:特殊方格的位置是任意的。而且,L型条块是可以旋转放置的。 为了区分出棋盘上的方格被不同的L型条块所覆盖,每个L型条块可以用不同的数字、颜色等来标记区分。 5. 扩展内容 可以采用可视化界面来表示各L型条块,显示其覆盖棋盘的情况。 经典的递归问题, 这是我的大代码, 只是本人很懒, 不想再优化
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值