zoukankan      html  css  js  c++  java
  • HDOJ1175连连看

    连连看

    Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 10796    Accepted Submission(s): 2869


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

    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 <iostream>
    #include <queue>
    #include <cstdio>
    using namespace std;
    const int MAXN = 1001;
    const int MAXINT = 999;
    bool flag;
    int n,m,sx,sy,ex,ey;
    int Hash[MAXN][MAXN],map[MAXN][MAXN];
    int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    struct node{
    	int x;
    	int y;
    	int turn;
    	int d;
    }start;
    
    queue<node> Q;
    
    void bfs()
    {
    	node now,t;
    	while(!Q.empty())
    	{
    		now=Q.front();
    		Q.pop();
    		if(now.x == ex && now.y == ey && now.turn <= 2)
    		{
    			flag = true;
    			return;
    		}
    		for(int i=0;i<4;i++)
    		{
    			t.x = now.x + dir[i][0];
    			t.y = now.y + dir[i][1];
    			if(now.d == i)
    			{
    				t.turn = now.turn;
    				t.d = i;
    			}
    			else
    			{
    				t.turn = now.turn + 1;
    				t.d = i;
    			}
    			if(t.x>=1 && t.x<=n && t.y>=1 &&t.y<=m && (map[t.x][t.y]==0||t.x==ex&&t.y==ey) && Hash[t.x][t.y]>=t.turn)
    			{
    				Hash[t.x][t.y] = t.turn;
    				Q.push(t);
    			}
    		}
    	}
    }
    int main()
    {
    	freopen("in.txt","r",stdin);
    	int i,j,t;
    	while(scanf("%d %d",&n,&m))
    	{
    		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--)
    		{
    			scanf("%d %d %d %d",&sx,&sy,&ex,&ey);
    			if((map[sx][sy]!=map[ex][ey]) || map[sx][sy]==0 || map[ex][ey]==0 || (sx==ex&&sy==ey))
    			{
    				puts("NO");
    				continue;
    			}
    			for(i=1;i<=n;i++)
    				for(j=1;j<=m;j++) 
    					Hash[i][j]=MAXINT;
    			while(!Q.empty()) 
    				Q.pop();
    			for(i=0;i<4;i++)
    			{
    				start.x = sx;
    				start.y = sy;
    				start.turn = 0;
    				start.d = i;
    				Q.push(start);
    			}
    			flag = false;
    			Hash[sx][sy] = 0;
    			bfs();
    			puts(flag ? "YES":"NO");
    		}
    	}
    	return 0;
    }




    #include <iostream>
    #include <queue>
    #include <cstdio>
    using namespace std;
    const int MAXN = 1001;
    const int MAXINT = 99999;
    int maps[MAXN][MAXN];
    int mark[MAXN][MAXN];
    int n, m, sx, sy, ex, ey, t;
    int mov[ 4 ][ 2 ] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
    
    struct Node {
    	int x;
    	int y;
    	int turn;
    	int dir;
    }Next,now;
    
    queue<Node> Q;
    
    void BFS() {
    	now.x = sx;   
    	now.y = sy;
    	mark[ sx ][ sy ] = 0;
    	now.dir = -1; 
    	now.turn = 0;
    	Q.push(now);
    	while(!Q.empty()) 
    	{
    		now = Q.front();
    		Q.pop();
    		if(now.x == ex && now.y == ey) 
    		{	
    			puts("YES");
    			return ;
    		}
    		//0下, 1上, 2左, 3右
    		for(int i = 0; i < 4; ++ i) 
    		{
    			Next.x = now.x + mov[ i ][ 0 ];
    			Next.y = now.y + mov[ i ][ 1 ];
    			Next.turn = now.turn;
    			Next.dir = now.dir;
    			if(now.dir == -1) 
    			{
    				Next.dir = i;
    				Next.turn = 0;
    			}
    			else if(now.dir != i) 
    			{
    
    				Next.turn ++;
    				Next.dir = i;
    			}
    			if(maps[ Next.x ][ Next.y ] && !(Next.x == ex && Next.y == ey) || Next.turn > 2) continue;
    			if(Next.x>=1 && Next.x<=n && Next.y>=1 && Next.y<=m && mark[ Next.x ][ Next.y ] >= Next.turn) 
    			{
    				mark[ Next.x ][ Next.y ] = Next.turn;
    				Q.push(Next);
    			}
    		}
    	}
    	puts("NO");
    }
    
    int main() 
    {
    	freopen("in.txt","r",stdin);
    	while(~scanf("%d %d", &n, &m)) 
    	{
    		if(n == 0 && m == 0) break;
    		for(int i = 1; i <= n; ++ i) 
    		{
    			for(int j = 1; j <= m; ++ j) 
    			{
    				scanf("%d", &maps[ i ][ j ]);
    			}
    		}
    		scanf("%d", &t);
    		while(t --) 
    		{
    			scanf("%d %d %d %d", &sx, &sy, &ex, &ey);
    			if(sx == ex && sy == ey) 
    			{
    
    				puts("NO");
    				continue;
    			}
    			if(maps[ sx ][ sy ] != maps[ ex ][ ey ] || maps[ sx ][ sy ] == 0 || maps[ ex ][ ey ] == 0) 
    			{
    
    
    				puts("NO");
    				continue;
    			}
    
    			for(int i = 1; i <= n; ++ i) 
    			{
    				for(int j = 1; j <= m; ++ j) 
    				{
    					mark[ i ][ j ] = MAXINT;
    				}
    			}
    			while(!Q.empty())
    				Q.pop();
    			BFS();
    		}
    	}
    	return 0;
    }

    DFS版本:
    #include <iostream>   
    #include <cstdio>   
    #include <cstring>   
    using namespace std;   
    
    int n, m, t, k, z;   
    int sx, sy, ex, ey;   
    int a[1005][1005];   
    bool map[1005][1005], flag;   
    
    void init()     //初始化函数   
    {   
    	flag = false;   
    	memset(map, false, sizeof(map));   
    }   
    
    void dfs(int x, int y, int z, int k)    //坐标(x,y)   
    {   
    	if(flag) return;   
    	if(x<=0 || y<=0 || x>n || y>m) return;  //若超界,返回   
    	if(k>=3) return;        //若转弯数已经超过3次,返回   
    	if(x == ex && y == ey)   
    	{   
    		flag = true;   
    		return;   
    	}   
    	if(k == 2)  //超强剪枝:若已经转两次弯,则目标坐标必须要在前进方向的前面,否则直接返回   
    	{   
    		if( !(z==1 && x>ex && y==ey  ||  z==2 && x<ex && y==ey   
    			||  z==3 && y>ey && x==ex  ||  z==4 && y<ey && x==ex) )   
    			return;   
    	}   
    	if(a[x][y] != 0) return;    //如果该点不是0,则不能走,返回   
    	if(map[x][y]) return;       //如果该点已经走过,返回   
    	map[x][y] = true;       //标记该点为走过   
    	if(z == 1)  //上   
    	{   
    		dfs(x-1, y, 1, k);   
    		dfs(x+1, y, 2, k+1);   
    		dfs(x, y-1, 3, k+1);   
    		dfs(x, y+1, 4, k+1);   
    	}   
    	else if(z == 2) //下   
    	{   
    		dfs(x-1, y, 1, k+1);   
    		dfs(x+1, y, 2, k);   
    		dfs(x, y-1, 3, k+1);   
    		dfs(x, y+1, 4, k+1);   
    	}   
    	else if(z == 3) //左   
    	{   
    		dfs(x-1, y, 1, k+1);   
    		dfs(x+1, y, 2, k+1);   
    		dfs(x, y-1, 3, k);   
    		dfs(x, y+1, 4, k+1);   
    	}   
    	else if(z == 4) //右   
    	{   
    		dfs(x-1, y, 1, k+1);   
    		dfs(x+1, y, 2, k+1);   
    		dfs(x, y-1, 3, k+1);   
    		dfs(x, y+1, 4, k);   
    	}   
    	map[x][y] = false;  //若深搜不成功,标记该点为未走过   
    }   
    
    int main()   
    {
    	freopen("in.txt","r",stdin);
    	int i, j;   
    	while(scanf("%d %d", &n, &m))   
    	{   
    		if(n==0 && m==0) break;   
    		for(i = 1; i <= n; i++)   
    			for(j = 1 ; j <= m; j++)   
    				scanf("%d", &a[i][j]);   
    		scanf("%d", &t);   
    		for(i = 0; i < t; i++)   
    		{   
    			init();   
    			scanf("%d %d %d %d", &sx, &sy, &ex, &ey);   
    			if(a[sx][sy]!=a[ex][ey] || a[sx][sy]==0 || a[ex][ey]==0 || sx==ex && sy==ey)
    				puts("NO");
    			else
    			{
    				dfs(sx-1, sy, 1, 0);   
    				dfs(sx+1, sy, 2, 0);   
    				dfs(sx, sy-1, 3, 0);   
    				dfs(sx, sy+1, 4, 0);   
    				if(flag) puts("YES");  
    				else puts("NO"); 
    			}
    		}   
    	}   
    
    	return 0;   
    }  



  • 相关阅读:
    Div+CSS 布局
    Windows Mobile 参考:
    Linux export的作用
    CSS(2)基本语法
    HTML(6)超链接
    HTML(5)常用的格式标签
    HTML(8)表格
    CSS(1) CSS简介
    HTML(7)图像、背景和颜色
    HTML(10)框架
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/5835324.html
Copyright © 2011-2022 走看看