zoukankan      html  css  js  c++  java
  • 时钟【BFS】

    题目大意:

    考虑将如此安排在一个 3 x 3 行列中的九个时钟:

    目标要找一个最小的移动顺序将所有的指针指向12点。下面原表格列出了9种不同的旋转指针的方法,每一种方法都叫一次移动。选择1到9号移动方法,将会使在表格中对应的时钟的指针顺时针旋转90度。

    移动方法 受影响的时钟

    1 ABDE

    2 ABC

    3 BCEF

    4 ADG

    5 BDEFH

    6 CFI

    7 DEGH

    8 GHI

    9 EFHI

    Example


    思路:

    很明显的广搜。由于只有3,6,9,12这4个数字(不然怎么转回去?),那么先离散化,就变成了1,2,3,4四个数字,要把这4个数字都变为4。 
    将每种变换方式的表打出来,再广搜+判重(9维数组水过),输出路径即可。


    代码:

    #include <cstdio>
    #include <iostream>
    #include <map>
    using namespace std;
    
    const int d[][10]={{},{1,2,4,5},{1,2,3},{2,3,5,6},{1,4,7},{2,4,5,6,8},{3,6,9},{4,5,7,8},{7,8,9},{5,6,8,9}};  //变换情况
    const int num[]={0,4,3,4,3,5,3,4,3,4};  //每种情况变换时钟的个数
    
    int head,tail,state[300001][10],father[300001],z[300001];
    bool p[5][5][5][5][5][5][5][5][5];  //判重专用
    
    bool inmap(int y)  //判重
    {
        if (p[state[y][1]][state[y][2]][state[y][3]][state[y][4]][state[y][5]][state[y][6]][state[y][7]][state[y][8]][state[y][9]])
         return true;
        p[state[y][1]][state[y][2]][state[y][3]][state[y][4]][state[y][5]][state[y][6]][state[y][7]][state[y][8]][state[y][9]]=1;
        return false;
    }
    
    void find(int x)  //递归输出路径
    {
        if (father[x]!=0) find(father[x]);
        printf("%d ",z[x]);
        return;
    }
    
    bool check(int x)  //判断是否达成目标
    {
        for (int i=1;i<=9;i++)
         if (state[x][i]!=4) return false;
        return true;
    }
    
    void bfs()
    {
        do
        {
            head++;
            for (int i=1;i<=9;i++)
            {
                tail++;
                for (int j=1;j<=9;j++)
                 state[tail][j]=state[head][j];  
                for (int j=0;j<num[i];j++)
                 state[tail][d[i][j]]=state[head][d[i][j]]%4+1;  //变换
                if (inmap(tail))   //已经出现过
                {
                    tail--;
                    continue;
                }
                z[tail]=i;  //记录变换方式
                father[tail]=head;
                if (check(tail))  //达成目标
                {
                    find(tail);
                    return;
                }
            }
        }
        while (head<tail);
    }
    
    int main()
    {
        head=-1;
        tail=0;
        for (int i=1;i<=3;i++)
         for (int j=1;j<=3;j++)
         {
            scanf("%d",&state[0][i*3-3+j]);
            state[0][i*3-3+j]/=3;  //离散
         }
        inmap(0);  
        bfs();
        return 0;
    }
  • 相关阅读:
    Idea中资源文件的设置和Java中类的权限
    Springboot中slf4j+log4j2的使用
    linux下修改文件查看样式(日期/文件大小)
    maven项目中引入外部jar
    01背包问题
    python爬取千千音乐
    【DataBase】SQL优化案例:其一
    【Uni-App】底部栏踩坑
    【Uni-App】UniApp转微信小程序发布应用
    【Uni-App】API笔记 P2
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9451845.html
Copyright © 2011-2022 走看看