zoukankan      html  css  js  c++  java
  • 【CodeVS1004】四子连棋-迭代加深搜索入门

    测试地址:四子连棋

    做法:这道题目要求最优解,然而裸的BFS所消耗的空间巨大,用DFS的话深度又深不可测,很容易在没用的分支上浪费很多时间。这时,就要用到迭代加深搜索。迭代加深搜索就是在DFS时给定一个深度上限,当搜索深度超过上限时就不再拓展。从1开始枚举深度上限,如果能找到解,这个上限就是最优解,否则就加大上限继续搜索。

    给出了迭代加深搜索的思想,这道题目就应该不是太难了,剩下的唯一需要注意的一点是:黑白两色需要轮流动棋,因此在搜索时还要记录上一手是哪个颜色的棋移动,判断时也要注意这一点,开始搜索时也要考虑黑先手和白先手两种情况。至此,这道题已经没什么难点了。

    所以,DFS时需要存储的状态有:两个空格的坐标,上一手棋的颜色和当前的深度。然后只要想到棋的移动等于空格的移动这一点即可。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define inf 1000000000
    using namespace std;
    char a[5][5];
    int ans,Ox1=0,Oy1,Ox2,Oy2,move[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    
    bool check() //检查当前棋盘是否构成四子连棋
    {
      for(int i=1;i<=4;i++)
      {
        if (a[i][1]==a[i][2]&&a[i][1]==a[i][3]&&a[i][1]==a[i][4]) return 1;
    	if (a[1][i]==a[2][i]&&a[1][i]==a[3][i]&&a[1][i]==a[4][i]) return 1;
      }
      if (a[1][1]==a[2][2]&&a[1][1]==a[3][3]&&a[1][1]==a[4][4]) return 1;
      if (a[1][4]==a[2][3]&&a[1][4]==a[3][2]&&a[1][4]==a[4][1]) return 1;
      return 0;
    }
    
    bool can(int x,int y,char p)
    {
      return x>=1&&x<=4&&y>=1&&y<=4&&a[x][y]!=p;
    }
    
    bool dfs(int x1,int y1,int x2,int y2,char pre,int step)
    {
      if (step==ans) //搜索深度达到上限,停止
      {
        if (check()) return 1;
    	else return 0;
      }
      for(int i=0;i<4;i++)
      {
        int nx1,ny1,nx2,ny2;
    	nx1=x1+move[i][0];
    	ny1=y1+move[i][1];
    	nx2=x2+move[i][0];
    	ny2=y2+move[i][1];
    	if (can(nx1,ny1,pre))
    	{
    	  swap(a[x1][y1],a[nx1][ny1]);
    	  if (dfs(nx1,ny1,x2,y2,(pre=='B'?'W':'B'),step+1)) return 1;
    	  swap(a[x1][y1],a[nx1][ny1]);
    	}
    	if (can(nx2,ny2,pre))
    	{
    	  swap(a[x2][y2],a[nx2][ny2]);
    	  if (dfs(x1,y1,nx2,ny2,(pre=='B'?'W':'B'),step+1)) return 1;
    	  swap(a[x2][y2],a[nx2][ny2]);
    	}
      }
      return 0;
    }
    
    int main()
    {
      for(int i=1;i<=4;i++)
      {
        char s[5];
        scanf("%s",s);
    	for(int j=1;j<=4;j++)
    	{
    	  a[i][j]=s[j-1];
          if (a[i][j]=='O')
    	  {
    	    if (Ox1==0) Ox1=i,Oy1=j;
    		else Ox2=i,Oy2=j;
    	  }
    	}
      }
      
      for(ans=1;ans<=inf;ans++) //ans枚举深度上限
      {
        if (dfs(Ox1,Oy1,Ox2,Oy2,'W',0)) break; //黑先手
    	if (dfs(Ox1,Oy1,Ox2,Oy2,'B',0)) break; //白先手
      }
      
      printf("%d",ans);
      
      return 0;
    }
    


  • 相关阅读:
    PHP 5.5.0 Alpha5 发布
    Ubuntu Touch 只是另一个 Android 皮肤?
    MariaDB 10 已经为动态列提供文档说明
    Percona Toolkit 2.1.9 发布,MySQL 管理工具
    Oracle Linux 6.4 发布
    Ruby 2.0.0 首个稳定版本(p0)发布
    Apache Pig 0.11.0 发布,大规模数据分析
    Node.js 0.8.21 稳定版发布
    红薯 MySQL 5.5 和 5.6 默认参数值的差异
    Django 1.5 正式版发布,支持 Python 3
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793896.html
Copyright © 2011-2022 走看看