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;
    }
  • 相关阅读:
    【NOIP模拟】寻找
    【NOIP模拟】行走
    【UVA11795】 Mega Man's Mission
    【UVA11825】Hackers' Crackdown
    【UVA1252】Twenty Questions
    BZOJ1718: [Usaco2006 Jan] Redundant Paths 分离的路径
    BZOJ1151: [CTSC2007]动物园zoo
    BZOJ1123: [POI2008]BLO
    BZOJ1040: [ZJOI2008]骑士
    POJ3417:Network
  • 原文地址:https://www.cnblogs.com/Zinn/p/9403666.html
Copyright © 2011-2022 走看看