zoukankan      html  css  js  c++  java
  • 【DFS】hdu 1175 连连看

    题目描述:

    http://acm.hdu.edu.cn/showproblem.php?pid=1175

     

    思路:

    两枚欲消棋子的位置由用户输入,我们以其中一枚棋子的位置作为深搜起点,搜索路径即为连线。

    从当前位置任选一个方向,走一步,若选择的方向与之前的方向一致,则没有转向,否则,转向次数加一。

    而新位置有 4 种可能:

    1.没有棋子

    2.没有棋子,但已经被走过 

    3.有棋子,且为目标棋子

    4.有棋子,但不是目标棋子

    只需要处理情况 1 和情况 3,其余两种情况不用考虑。

     

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,m;
    int maps[1000][1000];//棋盘信息 
    int y1,x1,y2,x2;//y行,x列 
    
    int dir[4][2] = {{0,-1}, {0,1}, {-1,0}, {1,0}};
    bool have_result;
    
    //row,col:当前访问位置 
    //pre_dir:之前连线的走向,用来判断是否转向 
    //turn_num:转向次数 
    void dfs(int row, int col,int pre_dir, int turn_num){
        //转折次数超过两次 或 已经判断出两个棋子可以消除了 
        if(turn_num > 2 || have_result){
            return;
        }
        
        //两个棋子可以消除 
        if(col == x2 && row == y2){
            have_result = true;
            return;
        }
        
        //任选一个方向,走一步 ,新位置有 4 种可能:
        //没有棋子
        //没有棋子,但已经被走过 
        //有棋子,且为目标棋子
        //有棋子,但不是目标棋子 
        for(int i=0;i<4;i++){
            int nx = col + dir[i][0];
            int ny = row + dir[i][1];
            
            if(nx>=0 && nx<m && ny>=0 && ny<n){
                int new_num = turn_num;
                //判断走到新位置时,是否进行了转向 
                if(pre_dir != -1 && i != pre_dir){
                    new_num++;
                }
                
                //新位置有棋子,且为目标棋子
                if(ny == y2 && nx == x2){
                    dfs(ny, nx, i, new_num);
                }
                else if(maps[ny][nx] == 0){//新位置没有棋子
                    maps[ny][nx] = -1;
                    dfs(ny, nx, i, new_num);
                    maps[ny][nx] = 0;
                }
                //另外两种情况不做处理 
            }
        }
    }
    
    int main(){
        while(scanf("%d %d", &n, &m) && (n||m)){
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    scanf("%d", &maps[i][j]);
                }
            }
            
            int k;
            scanf("%d", &k);
            for(int i=0;i<k;i++){
                scanf("%d %d %d %d", &y1, &x1, &y2, &x2);
                //记得减 1 
                y1--;x1--;y2--;x2--;
                
                have_result = false;
                //俩位置上有棋子,且棋子类型一致 
                if(maps[y1][x1] && maps[y2][x2] && maps[y1][x1] == maps[y2][x2]){
                    dfs(y1, x1, -1, 0);
                }
                
                if(have_result){
                    printf("YES
    ");
                }
                else{
                    printf("NO
    ");
                }
            }
        }
    } 
    
    //一组测试用例: 
    //3 4
    //5 0 1 0 
    //5 0 0 0 
    //1 4 0 5
    //4
    //3 4 1 1
    //1 1 3 4
    //2 1 3 4
    //3 4 2 1
    //0 0
    //
    //NO
    //NO
    //YES
    //YES

     

    作者:老干妈就泡面
    本文版权归作者和博客园共有,欢迎转载,但请给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    C# 编码约定
    SQL 合并多列为一行字符串
    Flex 粒子效果
    安装flashplayer 提示 "您尝试安装的 Adobe Flash Player" 版本不是最新版本. 请访问 Player 下载中心 获取最新、最安全版本"的解决方法
    Flex Builder 好用的插件
    【默认】博客正式开通
    Vulkanished2021重要内容简介
    论文读书笔记8
    论文读书笔记5
    论文读书笔记2
  • 原文地址:https://www.cnblogs.com/bjxqmy/p/14450061.html
Copyright © 2011-2022 走看看