迭代加深搜索[codevs1004 四子连棋]

迭代加深搜索

一、算法简介

  迭代加深搜索是在速度上接近广度优先搜索,空间上和深度优先搜索相当的搜索方式。由于在使用过程中引入了深度优先搜索,所以也可以当作深度优先搜索的优化方案。

  迭代加深搜索适用于当搜索深度没有明确上限的情况。

  例如上图的一棵搜索树,在进行深度优先搜索前先规定好这次搜索的最大深度dep,当搜索到达dep却还没搜索到结果时回溯。

  之后不断加大搜索深度,重新搜索,直到找到结果为止。虽然这样搜索次数会累计很多次,但每一次搜索的范围和下一次搜索的范围相比微不足道,所以整体搜索速度不会受太大影响。

  由于深度是从小到大逐渐增大的,所以当搜索到结果时可以保证搜索深度是最小的。这也是迭代加深搜索在一部分情况下可以代替广度优先搜索的原因(还比广搜省空间)。

二、算法图示

   假设G是需要搜索到的结果。

 

  

  当 dep = 1 时搜索深度为1,搜索到节点 A,未搜索到结果,dep++ 并进行下一次深搜。

  当 dep = 2 时搜索深度为2,搜索到节点 A,B,C,D 未搜索到结果,dep++ 并进行下一次深搜。

  当 dep = 3 时搜索深度为3,搜索到节点 A,B,C,D,E,G 搜索到结果G,停止全部搜索并记录记录结果。

三、[codevs 1004四子连棋]

  在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局。

 
 

  一般这样找最小搜索深度的题都用广度优先搜索写,但是由于广搜空间占用多,于是我们可以用迭代加深搜索作替代品。

  本题迭搜思路就是逐渐增加每一次下棋的最大移动步数,当棋盘状态满足题目所给条件时退出并记录步数。

  下面贴AC程序

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 int board[5][5];
 6 int movex[5]={0,-1,0,1,0},movey[5]={0,0,1,0,-1};
 7 int Ox1,Oy1,Ox2,Oy2,dep,f;
 8 int avalible(int a,int b,int k){
 9     if(board[a][b]!=k&&a>=1&&a<=4&&b>=1&&b<=4) return 1;
10     else return 0;
11 }
12 int jdg(){
13     for(int i=1;i<=4;i++){
14         if(board[i][1]==board[i][2]&&board[i][2]==board[i][3]&&board[i][3]==board[i][4]) return 1;
15         if(board[1][i]==board[2][i]&&board[2][i]==board[3][i]&&board[3][i]==board[4][i]) return 1;
16     }
17     if(board[1][1]==board[2][2]&&board[2][2]==board[3][3]&&board[3][3]==board[4][4]) return 1;
18     if(board[1][4]==board[2][3]&&board[2][3]==board[3][2]&&board[3][2]==board[4][1]) return 1;
19     return 0;
20 }
21 void dfs(int x,int y,int p,int q,int pre,int step){
22     if(jdg()){
23         f=1;
24         return ;
25     }
26     else if(step>dep) return ;
27     for(int i=1;i<=4;i++){
28         int nx=x+movex[i];
29         int ny=y+movey[i];
30         int np=p+movex[i];
31         int nq=q+movey[i];
32
33         if(avalible(nx,ny,pre)){
34             swap(board[x][y],board[nx][ny]);
35
36             dfs(nx,ny,p,q,board[x][y],step+1);
37
38             swap(board[x][y],board[nx][ny]);
39         }
40         if(avalible(np,nq,pre)){
41             swap(board[p][q],board[np][nq]);
42
43             dfs(x,y,np,nq,board[p][q],step+1);
44
45             swap(board[p][q],board[np][nq]);
46         }
47     }
48 }
49 int main(){
50     for(int i=1;i<=4;i++)
51         for(int j=1;j<=4;j++){
52             char ch;
53             cin>>ch;
54             if(ch==‘B‘) board[i][j]=1;
55             else if(ch==‘W‘) board[i][j]=2;
56             else board[i][j]=3;
57
58             if(board[i][j]==3&&!Ox1) Ox1=i,Oy1=j;
59             else if(board[i][j]==3) Ox2=i,Oy2=j;
60         }
61     for(dep=0;;dep++){
62         dfs(Ox1,Oy1,Ox2,Oy2,1,1);
63         dfs(Ox1,Oy1,Ox2,Oy2,2,1);
64         if(f){
65             printf("%d",dep);
66             return 0;
67         }
68     }
69     return 0;
70 }
时间: 2024-10-16 11:28:35

迭代加深搜索[codevs1004 四子连棋]的相关文章

【宽度优先搜索】神奇的状态压缩 CodeVs1004四子连棋

一.写在前面 其实这是一道大水题,而且还出在了数据最水的OJ上,所以实际上这题并没有什么难度.博主写这篇blog主要是想写下一个想法--状态压缩.状态压缩在记录.修改状态以及判重去重等方面有着极高的(←_←词穷了,诸位大致理解一下就好)效率.博主原本打算在blog介绍一种DP--状态压缩型动态规划,但动笔(键盘??)前,博主突然想起自己前些年写过的一道广搜题,当时在判重方面冥思苦想想出了一种类似状态压缩的方法,开心了好久,于是在此先抛砖引玉为状压DP做个铺垫. 二.题目 Description

【日常学习】【迭代加深搜索+哈希】codevs1004 四子连棋题解

转载请注明出处 [ametake版权所有]http://blog.csdn.net/ametake 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局. ● ○ ●   ○ ● ○ ● ● ○ ● ○ ○ ● ○   输入描述 Input

codevs1004四子连棋[BFS 哈希]

1004 四子连棋  时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局. ● ○ ●   ○ ● ○ ● ● ○ ● ○ ○ ● ○   输入描述 Inpu

Codevs 四子连棋 (迭代加深搜索)

题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局. ● ○ ●   ○ ● ○ ● ● ○ ● ○ ○ ● ○   输入描述 Input Description 从文件中读入一个4*4的初始棋局,黑棋子用B表示,白棋子用W表示,空格地带用

1004 四子连棋

1004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局. ● ○ ●   ○ ● ○ ● ● ○ ● ○ ○ ● ○   输入描述 In

Code[VS] 1004 四子连棋

[题意] 给定4*4的棋盘,每个位置上为"B"."W"或" ",表示黑棋.白棋或空格.定义目标棋局为有一行.一列或一条对角线上有相同颜色的四个子.黑白交替下,开始时任意一方先下,求最少多少步能达到目标棋局. [分析] 首先定义变量: 基本   q(1)wt[2][2]记录空格位置 (2)int p[4][4]记录值,黑棋存1,白棋存2,空格存0 哈希表 hash(1)long long data,存棋局的值,就是转化为10进制后存储 (2)nex

POJ1129Channel Allocation[迭代加深搜索 四色定理]

Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14601   Accepted: 7427 Description When a radio station is broadcasting over a very large area, repeaters are used to retransmit the signal so that every receiver has a s

Codevs 1004 四子连棋

1004 四子连棋 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个4*4的棋盘上摆放了14颗棋子,其中有7颗白色棋子,7颗黑色棋子,有两个空白地带,任何一颗黑白棋子都可以向上下左右四个方向移动到相邻的空格,这叫行棋一步,黑白双方交替走棋,任意一方可以先走,如果某个时刻使得任意一种颜色的棋子形成四个一线(包括斜线),这样的状态为目标棋局. ● ○ ●   ○ ● ○ ● ● ○ ● ○ ○ ● ○   输入描述 Input

UVA-11214 Guarding the Chessboard (迭代加深搜索)

题目大意:在一个国际象棋盘上放置皇后,使得目标全部被占领,求最少的皇后个数. 题目分析:迭代加深搜索,否则超时. 小技巧:用vis[0][r].vis[1][c].vis[2][r+c].vis[c-r+N]分别标志(r,c)位置相对应的行.列.主.副对角线有没有被占领(详见<入门经典(第2版)>P193),其中N表示任意一个比行数和列数都大(大于等于)的数. 代码如下: # include<iostream> # include<cstdio> # include&l