贪心思想解决皇后问题(下:冲突检测)

·  阅读 76

这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

贪心思想解决皇后问题(冲突检测)

解决思路

(1)先确定各个皇后的位置然后计算初始冲突数(如下面为 3,3,3,3)

image-20211118193244984

(2)选择冲突数最大的来调整皇后的行位置

(3)计算皇后移动到每一行的冲突数

image-20211118193716683

(4)移动皇后到最小的冲突位置上,重新计算冲突数

image-20211118194243683

(5)重复上面四个操作找到,每个皇后的冲突数都为0

代码

package demo1;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * 贪心思想解决皇后问题(冲突检测)
 */
@SuppressWarnings({"all"})
public class Queen {

    private  static int [] flag  = new int[1001]; // 创建数组来判断位置
    private static int [] sum = new int[100]; // 创建数组来记录冲突数

    public static void init(int[] flag, int num){

        for (int i = 1; i <= num ; i++) {
            long l = System.currentTimeMillis();
            int tmp = (int)( l % ( num - 1 ) ) + 1; // 使随机数范围为 1~num
            flag[i] = tmp ;

        }

    }

    private static void sumConflict(int[] flag, int[] sum, int num) {
        for (int i = 0; i < num + 1; i++) {
            sum[i] = 0;
        }
        for (int j = 1; j <= num ; j++) {
            for (int k = 1; k <= num ; k++) {
                if ( j != k && ( flag[j] == flag[k]  || flag[j] - flag[k] == j - k || flag[j] - flag[k] ==  k - j)){
                    sum[j]++;
                }
            }
        }
    }
    private static void sumConflict(int [] flag, int[] sum, int num, int max) {
        for (int i = 0; i < num + 1; i++) {
            sum[i] = 0;
        }
            for (int j = 1; j <= num ; j++) {
                flag[max] = j ;
                for (int k = 1; k <= num ; k++) {
                    if ( max != k && (j == flag[k] || k - max == flag[k] - j || max - k == flag[k] - j ) ){
                        sum[j]++;
                    }
                }
            }
    }


    private static void getTrueQueen(int[] flag, int[] sum, int i) {
        while (flagOK(sum,i)){
           int tmp = sumMax(sum,i);
           sumConflict(flag,sum,i,tmp);
           flag[tmp] = sumMin(sum,i);
           sumConflict(flag,sum,i);
        }
    }

    private static int sumMax(int[] sum,int num) {
        int max = 1;
        for (int i = 1; i <= num; i++) {
            if (sum[i] > sum[max]){
                max = i;
            }
        }
        return max;
    }
    private static int sumMin(int[] sum,int num) {
        int min = 1;
        for (int i = 1; i <= num; i++) {
            if (sum[i] < sum[min]){
                min = i;
            }
        }
        return min;
    }

    private static boolean flagOK(int sum[],int num) {
        for (int i = 1; i <= num; i++) {
            if (sum[i] != 0){
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int i = scanner.nextInt();
        // 初始化皇后位置,建议使用随机数来进行赋值
        init(flag,i);
        // 计算冲突数
        sumConflict(flag,sum,i);
        getTrueQueen(flag,sum,i);

        for (int j = 1; j <= i ; j++) {
            System.out.println(flag[j]);
        }
    }


}

复制代码
分类:
后端
标签: