hdu 1175 连连看
来源:互联网 发布:模拟电吉他软件下载 编辑:程序博客网 时间:2024/06/07 13:03
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 41 2 3 40 0 0 04 3 2 141 1 3 41 1 2 41 1 3 32 1 2 43 40 1 4 30 2 4 10 0 0 021 1 2 41 3 2 30 0
Sample Output
YESNONONONOYES
这道题的正解是搜索走的状态,但我用的是一种比较巧妙的方法。
首先说搜索,搜索的本质是什么?是枚举,是暴力。一般肯定是枚举走到哪里,走的路径,但这道题,因为有转弯不超过2个限制,可以枚举转弯的点。
复杂度为N2,非常理想。
怎么枚举转弯的点呢?画一张图,假设要从A走到B,你试试不转弯、转弯一次、转弯两次,就知道怎么枚举了。事实上,前两种情况可以归类到后一种情况里,有点FLOYD算法的味道。
还要写一个判断函数,判断同一直线上的两个点能否走通。
下面贴代码
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int x1,y1,x2,y2,m,n,a[1010][1010];int panduan(int xx1,int yy1,int xx2,int yy2)// to judge whether the road between(x1,y1) and (x2,y2) does not exist 0 Attention: using this function must ensure that x1==x2 or y1==y2{ int temp=1; if((xx1==xx2)&&(yy1==yy2)) return 1; if(xx1==xx2) { int yymin=min(yy1,yy2); int yymax=max(yy1,yy2); for(int i=yymin;i<=yymax;i++) { if(a[xx1][i]!=0) { if((xx1==x1)&&(i==y1)) continue; if((xx1==x2)&&(i==y2)) continue; temp=0; break; } } } else { int xxmax=max(xx1,xx2); int xxmin=min(xx1,xx2); for(int i=xxmin;i<=xxmax;i++) if(a[i][yy1]!=0) { if((i==x1)&&(yy1==y1)) continue; if((i==x2)&&(yy1==y2)) continue; temp=0; break; } } //printf("From(%d,%d) to (%d,%d):%d\n",xx1,yy1,xx2,yy2,temp); return temp;}int main(void){ //freopen("in.txt","r",stdin); //freopen("out2.txt","w",stdout); int q;//status stands for whether the two chosen chess can be offset while(scanf("%d%d",&n,&m)!=EOF) { if(n*m==0) break; memset(a,0,sizeof(a)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); scanf("%d",&q); while(q--) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if((x1<1)||(x1>n)||(x2<1)||(x2>n)||(y1<1)||(y1>m)||(y2<1)||(y2>m)) { printf("NO\n"); continue; } if((x1==x2)&&(y1==y2)) { printf("NO\n"); continue; } if((a[x1][y1]==a[x2][y2])&&(a[x1][y1]!=0))//Attention! I don't consider the situation that the two input is the same point { int status=0; int ymin=min(y1,y2),xmin=min(x1,x2),ymax=max(y1,y2),xmax=max(x1,x2); for(int y3=1;y3<=m;y3++) { if(panduan(x1,y1,x1,y3)&&panduan(x1,y3,x2,y3)&&panduan(x2,y3,x2,y2)) { status=1; break; } } if(status==0) { for(int x3=1;x3<=n;x3++) { if(panduan(x1,y1,x3,y1)&&panduan(x3,y1,x3,y2)&&panduan(x3,y2,x2,y2)) { status=1; break; } } } if(status==0) printf("NO\n"); else printf("YES\n"); } else printf("NO\n"); } } return 0;}
贴代码。
1 0
- hdu 1175 连连看
- hdu 1175 连连看
- hdu 1175 连连看
- HDU 1175 连连看
- HDU 1175 ( 连连看 )
- hdu 连连看 1175
- hdu 1175 连连看
- hdu 1175连连看
- HDU 1175 连连看
- hdu 1175 连连看
- HDU 1175 连连看
- HDU 1175 连连看
- HDU 1175 连连看
- HDU 1175 连连看
- hdu 1175 连连看
- hdu 1175 连连看
- HDU-1175 连连看
- HDU 1175 连连看
- Linux下随机10字符病毒的清除
- angularjs之间如何实现指令和指令之间的交互
- python——pip安装包教程
- HTTP协议详解(真的很经典)
- JMeter事务控制器(Transaction controller)
- hdu 1175 连连看
- 用指针作为函数参数
- java基础学习总结——数组
- Ubuntu16.04中安装Kermit
- kafka+zookeeper环境配置(Mac 或者 linux环境)
- Qt框架及模块认识
- [Mac] Atom 必备插件集合
- 排序算法-插入排序 Insertion Sort Θ(n-n)
- 十八、桥接模式Bridge(结构型模式)