【算法可视化】搜索算法专题

运行平台

Algorithm Visualizer

选数

[NOIP2002 普及组] 选数

// 导入可视化库 {
const { Tracer, Array1DTracer, LogTracer, Layout, VerticalLayout } = require('algorithm-visualizer');
// }

const N = 4, K = 3; //从包含4个元素的集合中选出3个数
let ans = 0 //方案数
const board =[3, 7, 12, 19];  //创建包含4个元素的一维数组
const chosen = [-1, -1, -1, -1]; //创建一维数组,初始为-1

// 定义跟踪器 {
const boardTracer = new Array1DTracer('集合'); //集合,一维数组
const chosenTracer = new Array1DTracer('选中元素'); //选中元素,一维数组
const logger = new LogTracer('枚举过程');
Layout.setRoot(new VerticalLayout([boardTracer, chosenTracer, logger ]));

boardTracer.set(board);
chosenTracer.set(chosen);
logger.println(`选数: 从${N}个元素中选出${K}个元素`);
Tracer.delay();
// }

function validState(sum) {
  	if(sum <= 1) return false;
  	for (let i = 2; i <= sum / i; i ++)
  		if(sum % i === 0) return false;
  	return true;
}

function dfs(t, last, sum) {
  if (t >= K) {
    let res = validState(sum)
    if(res) ans ++;
    // logger {
    logger.println(`所选${K}个数的和为${sum}`);
    if(res) logger.println(`${sum}是质数, 已找到${ans}组方案`);
    else logger.println(`${sum}不是质数`);
    logger.println('------------------------------------------------------------------');
    // }
    return;
  }

  for(let i = last + 1; i < N; i ++) {
    // visualize {
    logger.println(`${t + 1}个数选择${board[i]}`);
    boardTracer.select(i);
    Tracer.delay();
    chosenTracer.patch(t, board[i])
    Tracer.delay();
    // }
    dfs(t + 1, i, sum + board[i])
    // visualize {
    boardTracer.deselect(i);
    Tracer.delay();
    chosenTracer.patch(t, -1)
    chosenTracer.depatch(t)
    Tracer.delay();
    // }
  }
  
}

// logger {
logger.println('开始执行');
// }
dfs(0, -1, 0);
// logger {
logger.println(`完成,一共有${ans}组答案`);
// }

八皇后 Checker Challenge

[USACO1.5] 八皇后 Checker Challenge

// import visualization libraries {
const { Tracer, Array2DTracer, Array1DTracer, LogTracer, Randomize, Layout, VerticalLayout } = require('algorithm-visualizer');
// }
function filledArray(length, value) {
  return Array(...Array(length)).map(Number.prototype.valueOf, value);
}

const N = 6; //配置棋盘大小和初始状态
const board = (function createArray(N) {
  const result = [];
  for (let i = 0; i < N; i++) {
    result[i] = filledArray(N, 0);
  }
  return result;
}(N));
const queens = filledArray(N, -1);
const c = Randomize.Array1D({ N: N, value: () => Randomize.Integer({ min: 0, max: 0 }) }); //列状态
const u = Randomize.Array1D({ N: 2 * N, value: () => Randomize.Integer({ min: 0, max: 0 }) }); //对角线\状态
const v = Randomize.Array1D({ N: 2 * N, value: () => Randomize.Integer({ min: 0, max: 0 }) }); //对角线/状态

// define tracer variables {
const boardTracer = new Array2DTracer('棋盘');
const queenTracer = new Array1DTracer('皇后所在行');
const logger = new LogTracer('算法过程');
Layout.setRoot(new VerticalLayout([boardTracer, queenTracer, logger]));

boardTracer.set(board);
queenTracer.set(queens);
logger.println(`N皇后问题: ${N} X ${N}的棋盘放置 ${N} 个皇后`);
Tracer.delay();
// }

let ans = 0
function dfs(x) {
  if (x >= N) {
    ans ++;
    // logger {
    logger.println(`递归到底. 所有皇后放置成功,第 ${ans} 组解为: [${queens.join(', ')}]`);
    logger.println('------------------------------------------------------------------');
    // }
    return;
  }
  
  for(let y = 0; y < N; y ++)
  {
      if(c[y] === 0 && u[x + y] === 0 && v[y - x + N] === 0)
      {
          // logger {
          logger.println(`将第 ${x} 行的皇后放到第 ${y}`);
          boardTracer.select(x, y);
          Tracer.delay();
          queenTracer.patch(x, y);
          Tracer.delay();
          // }
          c[y] = u[x + y] = v[y - x + N] = 1;
          queens[x] = y;
          dfs(x + 1);
          c[y] = u[x + y] = v[y - x + N] = 0;
          // logger {
          boardTracer.deselect(x, y);
          Tracer.delay();
          queenTracer.patch(x, -1); 
          queenTracer.depatch(x, -1); 
          Tracer.delay();
          // }
      }
  }
}

// logger {
logger.println('开始执行');
// }
dfs(0);
// logger {
logger.println(`完成,一共有${ans}组解`);
// }

Lake Counting S

Lake Counting S

// import visualization libraries {
const {Tracer, Array2DTracer, LogTracer, Layout, VerticalLayout } = require('algorithm-visualizer');
// }
const n = 10, m = 12;
const G = [
    ['W','.','.','.','.','.','.','.','.','W','W','.'],
    ['.','W','W','W','.','.','.','.','.','W','W','W'],
    ['.','.','.','.','W','W','.','.','.','W','W','.'],
    ['.','.','.','.','.','.','.','.','.','W','W','.'],
    ['.','.','.','.','.','.','.','.','.','W','.','.'],
    ['.','.','W','.','.','.','.','.','.','W','.','.'],
    ['.','W','.','W','.','.','.','.','.','W','W','.'],
    ['W','.','W','.','W','.','.','.','.','.','W','.'],
    ['.','W','.','W','.','.','.','.','.','.','W','.'],
    ['.','.','W','.','.','.','.','.','.','.','W','.'],
];

// define tracer variables {
const tracer = new Array2DTracer("Lake Counting S");
const logger = new LogTracer('广度优先搜索');
Layout.setRoot(new VerticalLayout([tracer, logger]));
tracer.set(G);
Tracer.delay();
// }

const dx = [-1, -1, 0, 1, 1, 1, 0, -1];
const dy = [0, 1, 1, 1, 0, -1, -1, -1];
function bfs(x, y) {
  const Q = [];
  let node = [x, y]
  Q.push(node)
  tracer.patch(x, y, '.'); 
  Tracer.delay();
  while(Q.length > 0)
  {
      const node = Q.shift(); // dequeue
      x = node[0], y = node[1];
      for(let i = 0; i < 8; i ++)
      {
          let a = x + dx[i], b = y + dy[i];
          if(a < 0 || a >= n || b < 0 || b >= m) continue;
          if(G[a][b] == '.') continue;
          G[a][b] = '.';
          Q.push([a, b]);
          // visualize {
          tracer.patch(a, b, '.');
          Tracer.delay();
          // }
          
      }
  }
}
// logger {
logger.println('开始执行');
// }
let ans = 0;
for(let i = 0; i < n; i ++)
    for(let j = 0; j < m; j ++)
        if(G[i][j] == 'W')
        {
            // logger {
            logger.println(`开始搜索${i}${j}列开始的连通块`);
            // }
            ans ++;
            bfs(i, j);
            // logger {
            logger.println(`${i}${j}列开始的连通块搜索结束`);
            // }
        }
// logger {
logger.println(`搜索完成,一共找到${ans}个水坑`);
// }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少儿编程乔老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值