方法一(放大两倍):
for(j=0;j<w;j++)
if(s[j]=='\\') mat[2*i][2*j]=mat[2*i+1][2*j+1]=1;
else mat[2*i+1][2*j]=mat[2*i][2*j+1]=1;
把下图放大两倍。
得到以下表格。
@表示有斜线,空白处表示无斜线。
染色部分表示路径。
结合另外一位大牛的题解来看。
另外,考虑这点可不可以往右下走,只需考虑右下那个点可不可以左上走。
所以,左上,右上,左下,右下。四个方向可以缩减为两个方向。只需考虑这两种情况即可。
有了上面的表格。考虑斜走就容易了。
方法二(三倍法):
放大三倍后,发现
绿色格子数目为三倍前的三倍。
因此只需
if(n)printf("%d Cycles; the longest has length %d.\n",n,max_len/3);
输出max_len/3即可。
附上代码:
一:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int maxn=160;
int mat[maxn][maxn];
bool vis[maxn][maxn],flag;
char s[maxn/2];
int len,w,h;
int dir[8][2]={{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}};
void dfs(int i,int j)
{
vis[i][j]=true;
if(i==0 || j==0 || i==2*h-1 || j==2*w-1)
flag=false;
len++;
int m,n;
for(int k=0;k<8;k++)
{
int nx=i+dir[k][0];
int ny=j+dir[k][1];
if(nx>=0 && nx<2*h && ny>=0 && ny<2*w
&&!mat[nx][ny] && !vis[nx][ny])
{
if(k<4) dfs(nx,ny);
else
{
if(k==4 || k==7)
{
if(k==4)
{
m=i;
n=j;
}
else
{
m=nx;
n=ny;
}
if((mat[m-1][n] && mat[m][n-1]) && //左上
(!(m&1) && n&1 && mat[m-2][n-1] && mat[m+1][n]||
m&1 && !(n&1) && mat[m-1][n-2] && mat[m][n+1]))
dfs(nx,ny);
}
if(k==5 || k==6)
{
if(k==5)
{
m=i;
n=j;
}
else
{
m=nx;
n=ny;
}
if((mat[m-1][n] && mat[m][n+1]) && //右上
(m&1 && n&1 && mat[m][n-1] && mat[m-1][n+2] ||
!(m&1) && !(n&1) && mat[m-2][n+1] && mat[m+1][n]))
dfs(nx,ny);
}
}
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("705.txt","r",stdin);
#endif
int t=0;
while(scanf("%d%d",&w,&h)==2 && w)
{
memset(mat,0,sizeof(mat));
memset(vis,false,sizeof(vis));
int i,j;
for(i=0;i<h;i++)
{
scanf("%s",s);
for(j=0;j<w;j++)
if(s[j]=='\\') mat[2*i][2*j]=mat[2*i+1][2*j+1]=1;
else mat[2*i+1][2*j]=mat[2*i][2*j+1]=1;
}
/*for(i=0;i<2*h;i++)
{
for(j=0;j<2*w;j++)
printf("%d",mat[i][j]);
printf("\n");
}*/
int max_len=0,n=0;
for(i=0;i<2*h;i++)
for(j=0;j<2*w;j++)
if(!mat[i][j] && !vis[i][j])
{
flag=true;
len=0;
dfs(i,j);
if(flag)
{
n++;
if(max_len<len) max_len=len;
}
}
printf("Maze #%d:\n",++t);
if(n)printf("%d Cycles; the longest has length %d.\n",n,max_len);
else printf("There are no cycles.\n");
printf("\n");
// printf("%d %d\n",w,h);
}
return 0;
}
二:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int maxn=240;
int mat[maxn][maxn];
bool vis[maxn][maxn],flag;
char s[maxn/2];
int len,w,h;
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void dfs(int i,int j)
{
if(mat[i][j] || vis[i][j]) return;
if(i<=0 || j<=0 || i>=3*h-1 || j>=3*w-)
{
flag=false;
return;
}
vis[i][j]=true;
len++;
for(int k=0;k<4;k++)
dfs(i+dir[k][0],j+dir[k][1]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("705.txt","r",stdin);
//freopen("2.txt","w",stdout);
#endif
int t=0;
while(scanf("%d%d",&w,&h)==2 && w)
{
memset(mat,0,sizeof(mat));
memset(vis,false,sizeof(vis));
int i,j;
for(i=0;i<h;i++)
{
scanf("%s",s);
for(j=0;j<w;j++)
if(s[j]=='\\') mat[3*i][3*j]=mat[3*i+1][3*j+1]=mat[3*i+2][3*j+2]=1;
else mat[3*i+2][3*j]=mat[3*i+1][3*j+1]=mat[3*i][3*j+2]=1;
}
/*for(i=0;i<3*h;i++)
{
for(j=0;j<3*w;j++)
printf("%d",mat[i][j]);
printf("\n");
}*/
int max_len=0,n=0;
for(i=0;i<3*h;i++)
for(j=0;j<3*w;j++)
if(!mat[i][j] && !vis[i][j])
{
flag=true;
len=0;
dfs(i,j);
if(flag)
{
n++;
if(max_len<len) max_len=len;
}
}
printf("Maze #%d:\n",++t);
if(n)printf("%d Cycles; the longest has length %d.\n",n,max_len/3);
else printf("There are no cycles.\n");
printf("\n");
// printf("%d %d\n",w,h);
}
return 0;
}