第一次写:
错得很离谱
//
// main.cpp
// shuati
//
// Created by 布屿 on 2019/4/5.
// Copyright © 2019 布屿. All rights reserved.
#include<iostream>
using namespace std;
int map[1001][1001];
int record[1001][1001];//0是没走过的格子,1是走过的格子
int x[5]={0,0,0,1,-1};
int y[5]={0,1,-1,0,0};
int sum;
int search(int x0,int y0)//没判断边界
{
sum++;
if(map[x0][y0]==0)
{
for(int i=1;i<=4;i++)
{
if(map[x[i]][y[i]]==1&&record[x[i]][y[i]]==0)
{
record[x[i]][y[i]]=1;
search(x[i],y[i]);
record[x[i]][y[i]]=0;
}
}
}
else if(map[x0][y0]==1)
{
for(int i=1;i<=4;i++)
{
if(map[x[i]][y[i]]==0&&record[x[i]][y[i]]==0)
{
record[x[i]][y[i]]=1;
search(x[i],y[i]);
record[x[i]][y[i]]=0;
}
}
}
return sum;
}
int main()
{
int n,m;//n行迷宫,m行坐标。
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cin>>map[i][j];//没处理数据
}
int x0,y0;
for(int i=0;i<m;i++)
{
sum=0;
cin>>x0>>y0;
record[x0][y0]=1;
search(x0,y0);
record[x0][y0]=0;
cout<<sum-1<<endl;
}
return 0;
}
改到第二次交:
三个时间点超限
//
// main.cpp
// shuati
//
// Created by 布屿 on 2019/4/5.
// Copyright © 2019 布屿. All rights reserved.
//每输入一个坐标搜索一次,但是有的测试点会时间超限
#include<iostream>
using namespace std;
int map[1002][1002];
int record[1002][1002];//0是没走过的格子,1是走过的格子
int x[5]={0,0,0,1,-1};
int y[5]={0,1,-1,0,0};
int sum;
int n,m;//n行迷宫,m行坐标。
char c;
int search(int x0,int y0)
{
record[x0][y0]=1;
if(map[x0][y0]==0)
{
for(int i=1;i<=4;i++)
{
int xx=x0+x[i];
int yy=y0+y[i];
if(map[xx][yy]==1&&record[xx][yy]==0&&xx<=n&&yy<=n&&xx>0&&yy>0)
{
sum++;
search(xx,yy);
}
}
}
else if(map[x0][y0]==1)
{
for(int i=1;i<=4;i++)
{
int xx=x0+x[i];
int yy=y0+y[i];
if(map[xx][yy]==0&&record[xx][yy]==0&&xx<=n&&yy<=n&&xx>0&&yy>0)
{
sum++;
search(xx,yy);
}
}
}
return sum;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>c;
if(c=='0') map[i][j]=0;
if(c=='1') map[i][j]=1;
}
}
int x0,y0;
for(int i=0;i<m;i++)
{
sum=1;
cin>>x0>>y0;
record[x0][y0]=1;
search(x0,y0);
record[x0][y0]=0;
cout<<sum<<endl;
for(int j=1;j<=n;j++){
for(int k=1;k<=n;k++){
record[j][k]=0;
}
}
}
return 0;
}
第三次:
用了联通块思想,把题过了!
具体思路:
01迷宫由多个联通块组成,每个联通块内任意一点可以走遍整个联通块,并且路径长度=联通块内格子数。先搜遍每一个联通块,并把路径长度sum赋值给相应的record[][]数组,也就是每个坐标里存着当前坐标所在的联通块的格子数。再输入m个坐标,直接输出相应record数组中的数字即是从这一格开始能移动到多少格的路径长度。
//
// main.cpp
// shuati
//
// Created by 布屿 on 2019/4/5.
// Copyright © 2019 布屿. All rights reserved.
#include<iostream>
using namespace std;
int map[1002][1002];
int record[1002][1002];//0是没走过的格子,其他数字是走过的格子,数字代表当前联通块的格子总数
int x[5]={0,0,0,1,-1};
int y[5]={0,1,-1,0,0};
int record_x_y[2][1000001];
int sum;
int n,m;//n行迷宫,m行坐标。
char c;
void search(int x0,int y0)
{
sum++;
record[x0][y0]=1;
record_x_y[0][sum]=x0;
record_x_y[1][sum]=y0;
if(map[x0][y0]==0)
{
for(int i=1;i<=4;i++)
{
int xx=x0+x[i];
int yy=y0+y[i];
if(map[xx][yy]==1&&record[xx][yy]==0&&xx<=n&&yy<=n&&xx>0&&yy>0)
{
search(xx,yy);
}
}
}
else if(map[x0][y0]==1)
{
for(int i=1;i<=4;i++)
{
int xx=x0+x[i];
int yy=y0+y[i];
if(map[xx][yy]==0&&record[xx][yy]==0&&xx<=n&&yy<=n&&xx>0&&yy>0)
{
search(xx,yy);
}
}
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>c;
if(c=='0') map[i][j]=0;
if(c=='1') map[i][j]=1;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(!record[i][j])
{
record[i][j]=1;
sum=0;
search(i,j);
//现在sum的数量是联通块格子的数量
for(int k=1;k<=sum;k++)
record[record_x_y[0][k]][record_x_y[1][k]]=sum;
}
}
int x,y;
for(int i=1;i<=m;i++)
{
cin>>x>>y;
cout<<record[x][y]<<endl;
}
return 0;
}