您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM HDU