例1. POJ 1979 Red and Black
题意:由@为起点,周围最多有‘ . ’跟它相连通,不能越过‘ # ’。@本身也算一个
题意:由@为起点,周围最多有‘ . ’跟它相连通,不能越过‘ # ’。@本身也算一个
输入输出
Sample Input
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0
Sample Output
45
59
6
13
Sample Input
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0
Sample Output
45
59
6
13
代码:
#include<iostream>
using namespace std;
char map[25][25];
int n,m,num;
int i,j,ii,jj;
int dfs(int x,int y)
{
int i;
if(map[x+1][y]=='#'&&map[x-1][y]=='#'&&map[x][y+1]=='#'&&map[x][y-1]=='#')
{
return 0;
}
if(x<=n&&y<=m)
{
if(x+1<=n&&map[x+1][y]!='#')
{
num++;
map[x+1][y]='#';
dfs(x+1,y);
}
if(x-1>0&&map[x-1][y]!='#')
{
num++;
map[x-1][y]='#';
dfs(x-1,y);
}
if(y+1<=m&&map[x][y+1]!='#')
{
num++;
map[x][y+1]='#';
dfs(x,y+1);
}
if(y-1>0&&map[x][y-1]!='#')
{
num++;
map[x][y-1]='#';
dfs(x,y-1);
}
}
return 1;
}
int main()
{
while(cin>>m>>n&&m*n!=0)
{
if(m*n)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>map[i][j];
if(map[i][j]=='@')
{
ii=i;
jj=j;
}
}
}
for(j=0;j<=n+1;j++)
{
map[j][0]='#';
map[j][m+1]='#';
}
for(j=0;j<=m+1;j++)
{
map[0][j]='#';
map[n+1][j]='#';
}
num=1;
map[ii][jj]='#';
dfs(ii,jj);
cout<<num<<endl;
}
else
cout<<0<<endl;
}
return 0;
}
using namespace std;
char map[25][25];
int n,m,num;
int i,j,ii,jj;
int dfs(int x,int y)
{
int i;
if(map[x+1][y]=='#'&&map[x-1][y]=='#'&&map[x][y+1]=='#'&&map[x][y-1]=='#')
{
return 0;
}
if(x<=n&&y<=m)
{
if(x+1<=n&&map[x+1][y]!='#')
{
num++;
map[x+1][y]='#';
dfs(x+1,y);
}
if(x-1>0&&map[x-1][y]!='#')
{
num++;
map[x-1][y]='#';
dfs(x-1,y);
}
if(y+1<=m&&map[x][y+1]!='#')
{
num++;
map[x][y+1]='#';
dfs(x,y+1);
}
if(y-1>0&&map[x][y-1]!='#')
{
num++;
map[x][y-1]='#';
dfs(x,y-1);
}
}
return 1;
}
int main()
{
while(cin>>m>>n&&m*n!=0)
{
if(m*n)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>map[i][j];
if(map[i][j]=='@')
{
ii=i;
jj=j;
}
}
}
for(j=0;j<=n+1;j++)
{
map[j][0]='#';
map[j][m+1]='#';
}
for(j=0;j<=m+1;j++)
{
map[0][j]='#';
map[n+1][j]='#';
}
num=1;
map[ii][jj]='#';
dfs(ii,jj);
cout<<num<<endl;
}
else
cout<<0<<endl;
}
return 0;
}
思路:以@为起点上下左右四个方向搜索,到一个点计数器加1,把‘ . ’改为‘ # ’。当走到四周都为‘#’时,搜索结束。
例二: hdu 1010 Tempter of the Bone
题意:
在一张地图上,给定起点和终点,问能否恰好在t时刻到达终点
没有过的代码
#include<iostream>
#include<cstring>
#define N 10
using namespace std;
char mapp[N][N];
bool visited[N][N],flag;
int dic[4][2]={1,0,-1,0,0,1,0,-1};
int n,m,t,end_i,end_j;
int abs(int a,int b)
{
if(a<b) return b-a;
else return a-b;
}
void DFS(int i,int j,int c)
{
int u,w,k;
if(flag)return;
if(c>t)return;
if(i<0||i>=n||j<0||j>=m)return;
if(mapp[i][j]=='D')
{
if(c==t)
{
flag=true;
}
return ;
}
int temp=abs(i,end_i)+abs(j,end_j);
temp=t-temp-c;
if(temp&1)
return ;
for(k=0;k<4&&!flag;k++)
{
u=i+dic[k][0];
w=j+dic[k][1];
if(mapp[u][w]!='X')
if(visited[u][w]==false)
{
visited[u][w]==true;
DFS(u,w,c+1);
visited[u][w]==false;
if(flag)
return;
}
}
}
int main()
{
int i,j,k,x,y;
while(cin>>m>>n>>t&&(m||n||t))
{
k=0;
memset(visited,false,sizeof(visited));
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
cin>>mapp[i][j];
if(mapp[i][j]=='D')
{
end_i=i;
end_j=j;
}
if(mapp[i][j]=='S')
{
visited[i][j]=true;
x=i;
y=j;
}
if(mapp[i][j]=='X')
k++;
}
}
flag=false;
if(m*n-k-1>=t)
DFS(x,y,0);
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
#include<cstring>
#define N 10
using namespace std;
char mapp[N][N];
bool visited[N][N],flag;
int dic[4][2]={1,0,-1,0,0,1,0,-1};
int n,m,t,end_i,end_j;
int abs(int a,int b)
{
if(a<b) return b-a;
else return a-b;
}
void DFS(int i,int j,int c)
{
int u,w,k;
if(flag)return;
if(c>t)return;
if(i<0||i>=n||j<0||j>=m)return;
if(mapp[i][j]=='D')
{
if(c==t)
{
flag=true;
}
return ;
}
int temp=abs(i,end_i)+abs(j,end_j);
temp=t-temp-c;
if(temp&1)
return ;
for(k=0;k<4&&!flag;k++)
{
u=i+dic[k][0];
w=j+dic[k][1];
if(mapp[u][w]!='X')
if(visited[u][w]==false)
{
visited[u][w]==true;
DFS(u,w,c+1);
visited[u][w]==false;
if(flag)
return;
}
}
}
int main()
{
int i,j,k,x,y;
while(cin>>m>>n>>t&&(m||n||t))
{
k=0;
memset(visited,false,sizeof(visited));
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
cin>>mapp[i][j];
if(mapp[i][j]=='D')
{
end_i=i;
end_j=j;
}
if(mapp[i][j]=='S')
{
visited[i][j]=true;
x=i;
y=j;
}
if(mapp[i][j]=='X')
k++;
}
}
flag=false;
if(m*n-k-1>=t)
DFS(x,y,0);
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
过的代码
#include<iostream>
#include<cstring>
#define N 10
using namespace std;
char mapp[N][N];
bool visited[N][N],flag;
int dic[4][2]={1,0,-1,0,0,1,0,-1};
int n,m,t,end_i,end_j;
int abs(int a,int b)
{
if(a<b) return b-a;
else return a-b;
}
void DFS(int i,int j,int c)
{
int u,w,k;
if(flag)return;
if(c>t)return;
if(i<0||i>=n||j<0||j>=m)return;
if(mapp[i][j]=='D')
{
if(c==t)
{
flag=true;
}
return ;
}
int temp=abs(i,end_i)+abs(j,end_j);
temp=t-temp-c;
if(temp&1)
return ;
if(!visited[i-1][j]&&mapp[i-1][j]!='X')
{
visited[i-1][j]=true;
DFS(i-1,j,c+1);
visited[i-1][j]=false;
}
if(!visited[i+1][j]&&mapp[i+1][j]!='X')
{
visited[i+1][j]=true;
DFS(i+1,j,c+1);
visited[i+1][j]=false;
}
if(!visited[i][j-1]&&mapp[i][j-1]!='X')
{
visited[i][j-1]=true;
DFS(i,j-1,c+1);
visited[i][j-1]=false;
}
if(!visited[i][j+1]&&mapp[i][j+1]!='X')
{
visited[i][j+1]=true;
DFS(i,j+1,c+1);
visited[i][j+1]=false;
}
}
int main()
{
int i,j,k,x,y;
while(cin>>m>>n>>t&&(m||n||t))
{
k=0;
memset(visited,false,sizeof(visited));
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
cin>>mapp[i][j];
if(mapp[i][j]=='D')
{
end_i=i;
end_j=j;
}
if(mapp[i][j]=='S')
{
visited[i][j]=true;
x=i;
y=j;
}
if(mapp[i][j]=='X')
k++;
}
}
flag=false;
if(m*n-k-1>=t)
DFS(x,y,0);
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
#include<cstring>
#define N 10
using namespace std;
char mapp[N][N];
bool visited[N][N],flag;
int dic[4][2]={1,0,-1,0,0,1,0,-1};
int n,m,t,end_i,end_j;
int abs(int a,int b)
{
if(a<b) return b-a;
else return a-b;
}
void DFS(int i,int j,int c)
{
int u,w,k;
if(flag)return;
if(c>t)return;
if(i<0||i>=n||j<0||j>=m)return;
if(mapp[i][j]=='D')
{
if(c==t)
{
flag=true;
}
return ;
}
int temp=abs(i,end_i)+abs(j,end_j);
temp=t-temp-c;
if(temp&1)
return ;
if(!visited[i-1][j]&&mapp[i-1][j]!='X')
{
visited[i-1][j]=true;
DFS(i-1,j,c+1);
visited[i-1][j]=false;
}
if(!visited[i+1][j]&&mapp[i+1][j]!='X')
{
visited[i+1][j]=true;
DFS(i+1,j,c+1);
visited[i+1][j]=false;
}
if(!visited[i][j-1]&&mapp[i][j-1]!='X')
{
visited[i][j-1]=true;
DFS(i,j-1,c+1);
visited[i][j-1]=false;
}
if(!visited[i][j+1]&&mapp[i][j+1]!='X')
{
visited[i][j+1]=true;
DFS(i,j+1,c+1);
visited[i][j+1]=false;
}
}
int main()
{
int i,j,k,x,y;
while(cin>>m>>n>>t&&(m||n||t))
{
k=0;
memset(visited,false,sizeof(visited));
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
cin>>mapp[i][j];
if(mapp[i][j]=='D')
{
end_i=i;
end_j=j;
}
if(mapp[i][j]=='S')
{
visited[i][j]=true;
x=i;
y=j;
}
if(mapp[i][j]=='X')
k++;
}
}
flag=false;
if(m*n-k-1>=t)
DFS(x,y,0);
if(flag)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
思路:DFS+减枝,奇偶剪枝
第一个剪枝我们可以想到,当剩下的步数大于剩下的时间的时候,狗是不能走到的;
接下来我们来第二个剪枝:
我们把map的奇偶性以01编号:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
我们发现从0走一步一定走到1,从1走一步一定走到0。
也就是说,如果当前的狗所在的坐标与D的坐标奇偶性不一样,那么狗需要走奇数步。
同理,如果狗所在坐标与D的坐标奇偶性一样,那么狗需要走偶数步数。
也就是说,狗的坐标x、y和对2取余是它的奇偶性,Dxy和对2取余是D的奇偶性。
两个奇偶性一加再对2取余,拿这个余数去与剩下时间对2取余的余数作比较即可。