Js拓展_算法课程设计


一、合作题

1、破损的砝码问题

在这里插入图片描述

优化前代码

  // 找出所有砝码相加等于40的情况
  (function() {
    let i, j, k, l;
    for (i = 1; i <= 40; i++) {
      for (j = i + 1; j <= 40; j++) {
        for (k = j + 1; k <= 40; k++) {
          for (l = k + 1; l <= 40; l++) {
            if (i + j + k + l === 40) {
              calculate(i, j, k, l)
              // console.log(i, j, k, l)
            }
          }
        }
      }
    }
  })()
  // 判断 i,j,k,l 中是否存在可以称出1-40之间任意重量的解
  function calculate(i, j, k, l) {
    let x1, x2, x3, x4;
    let m, n = 0
    let sum = 0
    for (m = 1; m <= 40; m++) {
      for (x1 = -1; x1 <= 1; x1++) {
        for (x2 = -1; x2 <= 1; x2++) {
          for (x3 = -1; x3 <= 1; x3++) {
            for (x4 = -1; x4 <= 1; x4++) {
              if (i * x1 + j * x2 + k * x3 + l * x4 === m) {
                sum++;
              }
            }
          }
        }
      }
      // 计算通过测试的次数,若当前的值能通过本轮计算则n+1
      if (sum>=1) n++;
      // console.log(i,j,k,l)
      // console.log('sum:   ',sum)
      //清空sum的值
      sum=0
    }
    // 若通过了40次计算则输出该数列
    if (n===40){
      console.log(i,j,k,l)
      // return[i,j,k,l]
    }
  }

优化后

function m() {
  let sum = 0
  let k = 0
  let arr = [7,94,96,88,87]
  for (let i = 0; i < 4; i++) {
    sum += k
    k = 2 * sum + 1
    arr.push(k+40)
  }
  let judge =(num)=>{
    return num <100
  }
  console.log(arr.every(judge))
}
m()

2、猜算式

在这里插入图片描述
这一题我写的不好,用的是蛮力法,效率很低很低,我会去想其他方法的,暂时先这样吧

 <script>
function arrIn() {
  let a, b, Ji, m
  let arr1 = []
  let arr = []
  for (let i = 1; i < 10; i++) {
    i = i + ''
    arr.push(i)
  }
  // 将1-9转换成两个二位数
  for (let i = 1; i < arr.length - 1; i++) {
    for (let j = i + 1; j < arr.length; j++) {
      a = arr[i] + arr[j]
      b = arr[j] + arr[i]
      arr1.push(a)
      arr1.push(b)
    }
  }
  // 拿任意两个数进行求积
  for (let i = 0; i < arr1.length - 1; i++) {
    for (let j = i + 1; j < arr1.length; j++) {
      Ji = arr1[i] * arr1[j]
      for (let n = 100; n < 1000; n++) {
        m = Ji / n
        if (m % 1 === 0) {
          // 判断字符串是否有相同数字
          if (sort(arr1[i], arr1[j], m, n) !== null && m - 10 > 0) {
            console.log(sort(arr1[i], arr1[j], m, n)[0] + '*' + sort(arr1[i], arr1[j], m, n)[1] + '=' + sort(arr1[i], arr1[j], m, n)[2] + '*' + sort(arr1[i], arr1[j], m, n)[3])
          }
        }
      }
    }
  }
  return arr
}

// 判断字符串是否有相同数字
function sort(a, b, c, d) {
  a += ''
  b += ''
  c += ''
  d += ''
  let arr2 = []
  let sum = 0
  let nam = a + b + c + d
  for (let i = 0; i < nam.length; i++) {
    for (let j = i + 1; j < nam.length; j++) {
      if (nam.charAt(i) === nam.charAt(j) || nam.search('0')!== -1) {
        sum++
      }
    }
  }
  if (sum > 0) {
    return null
  } else {
    arr2.push(a)
    arr2.push(b)
    arr2.push(c)
    arr2.push(d)
    return arr2
  }
}
arrIn()

3.螺旋矩阵

在这里插入图片描述
在这里插入图片描述

import java.util.Scanner;

// 螺旋数组
public class spiral {
    static int[][] result = {};
    public static void main(String[] ages) {
        String inputText = "";
        do {
            System.out.println("请输入一个0-20的数字:");
            // 获取输入
            inputText = new Scanner(System.in).next();
            try {
                // 转型为算法需要的数据类型并进行参数校验
                int inputNumber = Integer.parseInt(inputText);
                if (inputNumber > 0 && inputNumber < 20) {
                    // 矩阵初始化(结果集)
                    result = new int[inputNumber][inputNumber];
                    // 递归起始方法
                    handle(inputNumber,0,1);
                    // 得到结果并打印
                    printResult();
                }else{
                    System.out.println("请输入一个0-20以内的数字");
                }
            } catch (StringIndexOutOfBoundsException e) {
                System.out.println("请输入数字");
            }
        } while (inputText.equals("exit"));
    }

    // 数据位置对应
    static void handle(int columnSize,int circle,int startNumber) {
        int start = startNumber;
        // 初始化圈数和每边输出的数量
        int columnLength = columnSize - circle * 2 - 1;
        // 判断列长度是否为0(当输入的是奇数时,最内层那一个的长度得出是0,需要另做区分)
        if(columnLength == 0){
            result[circle][circle] = start;
            return;// 最中间那个已经填充完毕,算法结束,直接结束递归
        }
        // 上边赋值
        for(int i = 0;i<columnLength;i++){
            result[circle][circle + i] = start;
            start ++;
        }
        // 左边赋值
        for(int i = 0;i < columnLength;i++){
            result[circle + i][columnSize - circle - 1] = start;
            start ++;
        }
        // 下边赋值
        for(int i = 0;i < columnLength;i++){
            result[columnSize - circle - 1][columnSize - circle - 1 - i] = start;
            start ++;
        }
        // 右边赋值
        for(int i = 0;i < columnLength;i++){
            result[columnSize - circle - 1 - i][circle] = start;
            start ++;
        }
        // 递归条件判断
        if(circle < Math.floor(columnSize / 2.0)){
            handle(columnSize,circle + 1,start);
        }
    }
    // 打印结果
    static void printResult() {
        // 遍历结果集打印结果
        for (int[] item : result) {
            for (int num : item) {
                System.out.print(num + "\t");
            }
            System.out.println("");
        }
    }
}

二、个人题目

1、找出亲密数

在这里插入图片描述

  function sum(num) {
    let sum = 0;
    for (let i = 1; i < num; i++) {
      if (num % i === 0) {
        console.log(i)
        sum += i;

      }
    }
    return sum;
  }

  for (let i = 1; i < 10000; i++) {
    //拿到i的约数和
    let b = sum(i);
    // console.log('sum(i):    ',sum(i))
    // console.log('i:    ',i)
    // 如果b的公因数之和与i相等 且i与b不相等则输出
    if (sum(b) === i && i !== b) {
      console.log(i + '和' + b + '是一对亲密数');
    }
  }

2.蛇形矩阵

在这里插入图片描述
在这里插入图片描述

import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        //获取用户输入的值
        int sor = new Scanner(System.in).nextInt();
        int num;//记录每行打印的数字
        int add;//记录相邻数字之间的增量
        int[] first = new int[100];//记录行首数字
        first[0] = 1;//从1开始
        for (int i = 1; i <= sor; i++) {
            add = i + 1;//每行的增量为行数+1
            num = first[0] + i - 1;//每行的第一个数是上一行的第一数 + 当前行 - 1
            int k = 0;//first数组的下标,每打印完一行则回到第一个位置
            for (int j = sor + 1 - i; j >= 1; j--) {//行数 + 数字个数一共为6个,6 - 当前行就是这样要打印的数字个数
                System.out.print(num + " ");
                first[k] = num;
                num = num + add;//每次加一次增量
                add++;//增量每次都会增加1
                k++;//用于控制数组的下标用来存储每行的数据
            }
            System.out.println();
        }
    }
}