zoukankan      html  css  js  c++  java
  • 连连看问题

    问题:

    Input
    输入数据有多组。每组数据的第一行有两个正整数n,m(0<n<=1000,0<m<1000),分别表示棋盘的行数与列数。在接下来的n行中,每行有m个非负整数描述棋盘的方格分布。0表示这个位置没有棋子,正整数表示棋子的类型。接下来的一行是一个正整数q(0<q<50),表示下面有q次询问。在接下来的q行里,每行有四个正整数x1,y1,x2,y2,表示询问第x1行y1列的棋子与第x2行y2列的棋子能不能消去。n=0,m=0时,输入结束。
    注意:询问之间无先后关系,都是针对当前状态的!
     
    Output
    每一组输入数据对应一行输出。如果能消去则输出"YES",不能则输出"NO"。
     
    Sample Input
    3 4
    1 2 3 4
    0 0 0 0
    4 3 2 1
    4
    1 1 3 4
    1 1 2 4
    1 1 3 3
    2 1 2 4
    3 4
    0 1 4 3
    0 2 4 1
    0 0 0 0
    2
    1 1 2 4
    1 3 2 3
    0 0

    Sample Output
    YES
    NO
    NO
    NO
    NO
    YES

    回答:

    #include <cstdio>  
    #include <cstdlib>  
    #include <cstring>  
    #include <cmath>  
    #include <queue>  
    #include <climits>  
     
    using namespace std;  
     
    const int MAX = 1003;  
    const int dirx[5] = {0,0,1,0,-1};  
    const int diry[5] = {0,1,0,-1,0};  
     
    bool visit[MAX][MAX];  
    int map[MAX][MAX];  
    int wan[MAX][MAX];  
    int n,m,bx,by;  
    bool mark;  
     
    bool yes(int x,int y,int dir){  
        int dx = bx - x;  
        int dy = by - y;  
        if(dx!=0)dx = dx/abs(dx);  
        if(dy!=0)dy = dy/abs(dy);  
        if(dx==dirx[dir] && dy==diry[dir])return true;  
        else return false;  
    }  
     
    void dfs(int x,int y,int cnt,int dir){  
        int i,tx,ty;  
        if(mark)return;  
        if(x<1 || y<1 || x>n || y>m || cnt>2)return;  
        //注意下面几个剪枝的顺序,顺序搞错了就会出错,因为最后一个元素非0  
        if(x==bx && y==by){  
            mark = true;  
            return;  
        }  
        if(cnt==2 && !yes(x,y,dir))return;//这个剪枝不强力,加了此剪枝时间只减少了18ms  
        if(map[x][y]!=0)return;  
        if(wan[x][y]!=-1 && wan[x][y]<=cnt)return;  
        wan[x][y] = cnt;  
        for(i=1;i<=4;++i){  
            tx = x + dirx[i];  
            ty = y + diry[i];  
            if(dir!=i){  
                dfs(tx,ty,cnt+1,i);  
            }else{  
                dfs(tx,ty,cnt,i);  
            }  
        }  
    }  
     
    int main(){  
    //  freopen("in.txt","r",stdin);  
        int i,j,t,ax,ay;  
        while(scanf("%d %d",&n,&m)!=EOF){  
            if(n==0 && m==0)break;  
            for(i=1;i<=n;++i){  
                for(j=1;j<=m;++j){  
                    scanf("%d",&map[i][j]);  
                }  
            }  
            scanf("%d",&t);  
            while(t--){  
                memset(wan,-1,sizeof(wan));  
                scanf("%d %d %d %d",&ax,&ay,&bx,&by);  
                mark = false;  
                if(map[ax][ay]!=map[bx][by] || map[ax][ay]==0){  
                    printf("NO ");  
                    continue;  
                }  
                wan[ax][ay] = 0;  
                for(i=1;i<=4;++i){  
                    dfs(ax+dirx[i],ay+diry[i],0,i);  
                }  
                if(mark){  
                    printf("YES ");  
                }else{  
                    printf("NO ");  
                }  
            }  
        }  
          
        return 0;  
    }

  • 相关阅读:
    HTTP协议
    Python学习--装饰器、列表生成式、生成器、map filter、json处理
    Python学习--多线程&多进程
    Python学习--发送邮件
    Python学习--异常处理
    【第五节】【Python学习】【configparser模块】
    【第一节】【shell脚本】【文件里的内容与变量中的内容大小写替换】
    【Python】【多线程多进程】
    【Selenium学习】【拖动滚动条】
    【Python】【异常的获取与处理】
  • 原文地址:https://www.cnblogs.com/benchao/p/4508855.html
Copyright © 2011-2022 走看看