HDU 1175 连连看
2016-07-16 16:58
295 查看
连连看,要想两点相连,最多走三个直线,这道题我并没有用传统的搜索做,而是首先想到,这种情况判断是否能走到,因为已经知道起点和终点,所以就不用想搜索那样把每种可能性都遍历一遍,会省一些运行时间,设想如果是只许拐一次弯,很简单,用终点C坐标减去起点B坐标,路只有两条,只需判断至少有一条路中所有的点为0,则可以走通,如果拐两次,则只需判断起点直接可以到达的点中,有一个点满足上述B,如果设两拐起点为A,判断A的四个方向有点,再判断点是不是B。
以前写的代码没怎么做优化处理,所以看着很多,其实原理很简单。
以前写的代码没怎么做优化处理,所以看着很多,其实原理很简单。
#include<stdio.h> #include<string.h> int start(int x1,int y1,int x2,int y2,int m[600][600]) { if(x1==x2&&y1==y2)//是否重合 return 0; if(m[x1][y1]!=m[x2][y2])//是否相等 return 0; if(m[x1][y1]==0||m[x2][y2]==0)//是否等于0 return 0; return 1; } int discover(int x,int y,int x2,int y2,int m[600][600]) { int sumx=0,sumy=0,i; if(x2>=x&&y2>=y) { for(i=1; i<x2-x; i++) sumx+=m[x+i][y]; for(i=1; i<y2-y; i++) sumx+=m[x2][y+i]; for(i=1; i<y2-y; i++) sumy+=m[x][y+i]; for(i=1; i<x2-x; i++) sumy+=m[x+i][y2]; if(sumx==0||sumy==0) return 1; else return 0; } if(x2>=x&&y2<=y) { for(i=1; i<x2-x; i++) sumx+=m[x+i][y]; for(i=1; y-i>y2; i++) sumx+=m[x2][y-i]; for(i=1; y-i>y2; i++) sumy+=m[x][y-i]; for(i=1; i<x2-x; i++) sumy+=m[x+i][y2]; if(sumx==0||sumy==0) return 1; else return 0; } if(x2<=x&&y2>=y) { for(i=1; x-i>x2; i++) sumx+=m[x-i][y]; for(i=1; i<y2-y; i++) sumx+=m[x2][y+i]; for(i=1; i<y2-y; i++) sumy+=m[x][y+i]; for(i=1; x-i>x2; i++) sumy+=m[x-i][y2]; if(sumx==0||sumy==0) return 1; else return 0; } if(x2<=x&&y2<=y) { for(i=1; x-i>x2; i++) sumx+=m[x-i][y]; for(i=1; y-i>y2; i++) sumx+=m[x2][y-i]; for(i=1; y-i>y2; i++) sumy+=m[x][y-i]; for(i=1; x-i>x2; i++) sumy+=m[x-i][y2]; if(sumx==0||sumy==0) return 1; else return 0; } } int dfs(int x1,int y1,int x2,int y2,int m[600][600]) { int i,x,y; for(i=1; i+x1<600; i++)//向下走 { x=x1+i; y=y1; if(x1+i==x2&&y1==y2) return 1; if(m[x1+i][y1]!=0) break; if(discover(x,y,x2,y2,m)) return 1; } for(i=1; i+y1<600; i++)//向右走 { x=x1; y=y1+i; if(x1==x2&&y1+i==y2) return 1; if(m[x1][y1+i]!=0) break; if(discover(x,y,x2,y2,m)) return 1; } for(i=1; x1-i>=0; i++)//向上走 { x=x1-i; y=y1; if(x1-i==x2&&y1==y2) return 1; if(m[x1-i][y1]!=0) break; if(discover(x,y,x2,y2,m)) return 1; } for(i=1; y1-i>=0; i++)//向左走 { x=x1; y=y1-i; if(x1==x2&&y1-i==y2) return 1; if(m[x1][y1-i]!=0) break; if(discover(x,y,x2,y2,m)) return 1; } return 0; } int main () { int n,m,i,j,q,x1,y1,x2,y2,e,f,map[600][600]; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; memset(map,-1,sizeof(map)); for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { scanf("%d",&map[i][j]); } } scanf("%d",&q); while(q--) { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); if(start(x1,y1,x2,y2,map)) { if(dfs(x1,y1,x2,y2,map)) printf("YES\n"); else printf("NO\n"); } else printf("NO\n"); } } return 0; }
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACMer博客瀑布流分析
- ACM程序设计大赛题目分类
- 2015年acm国内排名
- 计算字符串最后一个单词长度
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833
- 【HDU 5366】The mook jong 详解