连连看问题

问题:

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\n");  
                continue;  
            }  
            wan[ax][ay] = 0;  
            for(i=1;i<=4;++i){  
                dfs(ax+dirx[i],ay+diry[i],0,i);  
            }  
            if(mark){  
                printf("YES\n");  
            }else{  
                printf("NO\n");  
            }  
        }  
    }  
      
    return 0;  
}

时间: 2024-08-06 20:08:18

连连看问题的相关文章

宠物连连看2完整Android代码项目

宠物连连看2完整代码,该源代码支持多种风格的连连看游戏的,如有国旗类的连连看,还有宠物连连看的等,主要的功能实现了无尽关卡挑战模式.还有催命倒计时,以及链接提示,暂停.多样图片集,挑战眼力和速度等,而且还带有广告自行解除就可以也可学习怎样加广告.大屏手机和平板玩才够爽啊.希望可以帮到大家的学习. 源代码下载:http://code.662p.com/view/5414.html <ignore_js_op><ignore_js_op> <ignore_js_op><

连连看的设计与实现——四人小组项目(NABCD)

小组名称:天天向上 成员:王森.张政,张金生,栾骄阳 题目:连连看游戏 NABCD N(需求) 游戏最大的乐趣在于玩法,我们要想在众多的连连看游戏当中脱颖而出,就需要增加更多富有乐趣.吸引用户的玩法. A( 做法) 讲过小组讨论以及咨询同学,想了一些具有趣味性的玩法,如下: 玩法1:增加时间图标按钮,如果时间图标按钮消除,系统会增加游戏时间. 玩法2:用户在系统提供的图片中选择喜欢的按钮图片,系统根据用户的选择生成一关. 玩法3:系统设有排行榜功能.在一局游戏中,当两个按钮消除成功时,增加游戏积

四人小组项目——连连看

小组名称:天天向上 组长:王森 组员:张政,张金生,栾骄阳 题目:连连看游戏 项目期限:十周内,暂定2016.9.10-2016.11.19 需求分析: 1.概要:玩家可以将2个相同图案的牌连接起来,连接不多于3根直线,就可以成功的将两个图片消除. 2.操作:第一次使用鼠标点击游戏界面中的牌,该牌此时为“被选中”以特殊方式显示:再次以鼠标点击其他牌,若该牌与被选中的牌图案相同,且把第一个牌到第二个牌连起来,中间的直线不超过3根,则消掉这一对牌,否则第一个牌变为未被选中状态,而第二张牌变成选中状态

HDU 1175 连连看(DFS)

Problem Description “连连看”相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过.玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能

本人第一个android游戏《新连连看》上架

经过艰苦奋战了几天,本人的第一个android游戏<新连连看>最终完毕了第一个版本号,比較简陋.另一部分功能保留没有开放.等第二个版本号再上.用的libgdx框架.可能不是非常出名,可是本人认为真的是非常好用的. 希望大家先去玩一下,然后给我提一些改进的意见.稍后我会进行改进.并在完好后发布源代码供讨论.批评. 传送门:http://app.lenovo.com/app/14452187.html ------------------------------------------------

结对项目-小游戏连连看

我与我的结对同学作的是连连看小游戏,由王庆祥同学进行编码,我来检查以及运行监测,最后得结果如下图: 最后附上我的GitHub地址:https://github.com/jiaweihao/Test.git

hdu 1175 连连看(模拟循环队列)

连连看 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 18149    Accepted Submission(s): 4741 Problem Description "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条

BZOJ 2661 连连看(费用流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2661 题意:给出一个区间[a,b]中的全部整数,如果其中某两个数x,y(设x>y)的平方差x^2-y^2是一个完全平方数z^2,并且y与z互质,那么就可以将x和y一起消除,同时得到x+y点分数.要求就是,消除的数对尽可能多的前提下,得到的分数尽量多. 思路:首先暴力出所有合法的数对(x,y).然后将每个用到的数字拆成两个点,每个数对连一条边.最后的答案除以2即可. struct nod

Eclipse SWT开发教程以及一个连连看游戏的代码实现下载

原创整理不易,转载请标明出处:Eclipse SWT开发教程以及一个连连看游戏的代码实现下载 代码下载地址:http://www.zuidaima.com/share/1772672482675712.htm 我在前面讲过:如果讲GUI编程一味只讲各个控件的使用方法,那么纯粹是浪费大家时间,如果出书,那绝对是骗钱的.所以我并不会详细地讲解SWT各个控件的具体使用方法.然而的众所周知,Eclipse的UI界面是建立在SWT基础之上的,如果一字不提SWT,似乎也不大可能.SWT是一个优秀的GUI编程

HDU - 1175 连连看 DFS (记录方向)

连连看HDU - 1175 "连连看"相信很多人都玩过.没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子.如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去.不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的.现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过. 玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能