zoukankan      html  css  js  c++  java
  • hdu 3500 还是搜索

    这道题目由于每走一步的时候毛毛球是可以变换的 换言之 主体不唯一 所以这里搜索的设计有变化

    再就是几个回溯的过程要注意。,。  小心使得万年船

    #include <iostream>
    #include <cstdio>
    using namespace std;
    char map[10][10];
    int num;
    int flag;
    int mmove;
    int dir[4][2] = {{-1,0},{0,-1},{0,1},{1,0}}; //U、L、R、D
    char tow[4] = {'U','L','R','D'};
    
    struct node
    {
        int x,y;
        int direction;
    }path[15];
    
    int is_in(int x, int y) //判断是否在游戏界面中
    {
        if(x >= 0 && x <= 6 && y >= 0 && y <= 7)
            return 1;
        else
            return 0;
    }
    
    void dfs(int cur)
    {
        if(cur == num)
        {
        //走了num-1步之后直接返回
        /*
          没成功走一次,都会把一个毛毛球推出游戏界面,所以最多只可能走num-1步
        */
            flag = 1; //已经走完了相应的步数
            return;
        }
    
        for(int i=0; i<=6; i++)
        {
            for(int j=0; j<=7; j++)
            {
                if(map[i][j] == 'O') //按顺序进行搜索,如果搜索到了一个毛毛球,就看它是否能够移动
                {
                    mmove = 0;
                    for(int d=0; d<4; d++)
                    {
                        int nx = i + dir[d][0];
                        int ny = j + dir[d][1];
                        if(is_in(nx, ny) && map[nx][ny] == 'O') //前方有毛毛球阻碍无法移动,直接continue选取下一个方向
                            continue;
    
                        /*
                        while循环这部分处理是关键,这里主要要处理好手拨动的毛毛球遇到另外一个球时要处理的状况,以及
                        撞击力量的传递处理。
                        */
                        while(is_in(nx, ny))
                        {
                            nx += dir[d][0];
                            ny += dir[d][1];
    
                             /*    遇到毛毛球k,其前面那个必然要为'O',而这个毛毛球k必须变为'X'。
                                 通过while循环就可以处理好遇到毛毛球的情况,并且处理好撞击传递
                                的情况,例如第二组数据的撞击传递,所以这里设计的还是很巧妙的。
                              */
    
                            if(map[nx][ny] == 'O')
                            {
                                mmove = 1; //手拨动的毛毛球map[i][j]是可以移动的
                                map[nx][ny] = 'X';
                                map[nx - dir[d][0]][ny - dir[d][1]] = 'O';
                            }
                        }
    
                        if(mmove) //可以移动,进行记录
                        {
                            map[i][j] = 'X'; //移动之后原来的位置当然要置为'X'
                            path[cur].x = i;
                            path[cur].y = j;
                            path[cur].direction = d;
    
    
                            dfs(cur + 1);
                            //回溯之后
                            if(flag == 1)  //已经走完了就应该直接返回
                                 return;
    
                                      //反方向走
                            nx -= dir[d][0];
                            ny -= dir[d][1];
                            while(nx != i || ny != j) //一直会推到手拨动球的起点map[i][j]
                            {
                                if(map[nx][ny] == 'O')  /*这说明是前面的球移动到此处的一个位置,
                                                         所以该位置还原成'X',而它后面的那个位置应该
                                                         还原成'O'
                                                         */
                                {
                                    map[nx][ny] = 'X';
                                    map[nx + dir[d][0]][ny + dir[d][1]] = 'O';
                                }
                                nx -= dir[d][0];
                                ny -= dir[d][1];
    
                            }
                            map[i][j] = 'O'; //起点还原
    
                        }
    
                    }
    
                }
            }
        }
    }
    
    
    
    int main()
    {
        int kase = 1;
        while(scanf("%s",map[0]) != EOF)
        {
            num = flag = 0;
            for(int i=1; i<=6; i++)
            {
                scanf("%s",map[i]);
            }
    
            for(int i=0; i<=6; i++)
            {
                for(int j=0; j<=7; j++)
                {
                    if(map[i][j] == 'O')
                    {
                        num++; //记录毛毛球的个数
                    }
                }
            }
    
            dfs(1);
            if(kase != 1)
                cout<<endl;
            cout<<"CASE #"<<kase++<<":"<<endl;
            for(int i = 1; i<=num-1; i++)
            {
                cout<<path[i].x<<" "<<path[i].y<<" "<<tow[path[i].direction]<<endl;
            }
        }
        return 0;
    }
    
  • 相关阅读:
    oracle行转列
    中国软件开发标准各项文档模板下载(附模版)
    熙熙SQLCE类熙熙
    用反射技术实现将泛型集合类中的数据导出成EXCEL
    WinCE 5.0 中文模拟器SDK(VS2005, VS2008)的配置
    OpenFrameworks x kinect x Android
    Ubuntu11.04软件源增强版
    信号量与自旋锁
    android 编写命令行测试程序
    在 Ubuntu 上换用 OSS4 声音系统
  • 原文地址:https://www.cnblogs.com/z1141000271/p/5950679.html
Copyright © 2011-2022 走看看