zoukankan      html  css  js  c++  java
  • 洛谷 P1312 [ NOIP 2011 ] Mayan游戏 —— 搜索+模拟

    题目:https://www.luogu.org/problemnew/show/P1312

    还是不擅长这种题,所以参考了一下TJ;

    其实也很好搜,按字典序,先搜右移,再搜左移;

    不交换相同颜色的两个格子,因为浪费;

    左移就不交换了,避免重复,只有左边为空时左移;

    写个处理下落的 fall 函数,再写个处理消格子的 refresh 函数(其中用到了 fall ),就可以方便地搜索了!

    我存的是行和列,所以和坐标正好相反,一定要注意字典序的处理!

    优美。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,mp[10][10][10],ansx[10],ansy[10],ansm[10];
    bool vis[10][10];
    void fall(int s)
    {
        for(int j=1,sz;j<=5;j++)
        {
            sz=0;
            for(int i=1;i<=7;i++)
                if(mp[s][i][j])mp[s][++sz][j]=mp[s][i][j];
            while(sz<7)mp[s][++sz][j]=0;//
        }
    }
    void refresh(int s)
    {
        bool fl=0;
        while(1)
        {
            fl=0; fall(s);
            for(int i=1;i<=7;i++)
                for(int j=1;j<=5;j++)
                {
                    if(!mp[s][i][j])continue;//
                    if(i<=5&&mp[s][i][j]==mp[s][i+1][j]&&mp[s][i][j]==mp[s][i+2][j])
                    {
                        fl=1;
                        vis[i][j]=vis[i+1][j]=vis[i+2][j]=1;
                    }
                    if(j<=3&&mp[s][i][j]==mp[s][i][j+1]&&mp[s][i][j]==mp[s][i][j+2])
                    {
                        fl=1;
                        vis[i][j]=vis[i][j+1]=vis[i][j+2]=1;
                    }
                }
            if(!fl)break;
            for(int i=1;i<=7;i++)
                for(int j=1;j<=5;j++)
                    if(vis[i][j])mp[s][i][j]=0,vis[i][j]=0;
        }
    }
    bool dfs(int s)
    {
        for(int i=1;i<=7;i++)
            for(int j=1;j<=5;j++)mp[s][i][j]=mp[s-1][i][j];
        refresh(s);
        if(s>n)
        {
            for(int j=1;j<=5;j++)
                if(mp[s][1][j])return 0;
            return 1;
        }
        for(int j=1;j<=5;j++)//字典序! 
            for(int i=1;i<=7;i++)    if(mp[s][i][j])
            {
                if(j<5&&mp[s][i][j]!=mp[s][i][j+1])//1
                {
                    ansx[s]=i; ansy[s]=j; ansm[s]=1;
                    swap(mp[s][i][j],mp[s][i][j+1]);
                    if(dfs(s+1))return 1;
                    swap(mp[s][i][j],mp[s][i][j+1]);
                }
                if(j>1&&!mp[s][i][j-1])//-1
                {
                    ansx[s]=i; ansy[s]=j; ansm[s]=-1;
                    swap(mp[s][i][j],mp[s][i][j-1]);
                    if(dfs(s+1))return 1;
                    swap(mp[s][i][j],mp[s][i][j-1]);
                }
            }
        return 0;
    }
    int main()
    {
        scanf("%d",&n);
        for(int j=1;j<=5;j++)
            for(int i=1,x;i<=8;i++)
            {
                scanf("%d",&x); if(!x)break;
                mp[0][i][j]=x;
            }
        if(dfs(1))//1
        {
            for(int i=1;i<=n;i++)
                printf("%d %d %d
    ",ansy[i]-1,ansx[i]-1,ansm[i]);//坐标! 
        }
        else printf("-1
    ");
        return 0;
    }
  • 相关阅读:
    小希的迷宫(hdu1272 并查集)
    How many Fibs?(poj 2413)大数斐波那契
    图练习-BFS-从起点到目标点的最短步数(sdut 2830)邻接边表
    最大流(EK)
    趣写算法系列之--匈牙利算法(真的很好理解)
    Saving Princess claire_(hdu 4308 bfs模板题)
    Knight Moves(hdu1372 bfs模板题)
    The Die Is Cast(poj 1481简单的双dfs)
    Oil Deposits(poj 1526 DFS入门题)
    WTL:下载、安装、初见
  • 原文地址:https://www.cnblogs.com/Zinn/p/9403666.html
Copyright © 2011-2022 走看看