1、问题描述
2、问题简化的一个步骤是对两点之间是否存在障碍物的判断:通过统计某一区间之间障碍的数量,并用以作差来判断给定区间内是否存在障碍物;决策树在本题是十分明显的,是通过每一step来进行的,同一step层内,有若干子节点,可以进行分类(DFS搜索)
3、
#include <iostream>
#include<cmath>
#include<cstring>
using namespace std;
#define maxn 100+1
#define maxt 10000
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int field[maxn][maxn];
int row[maxn][maxn],col[maxn][maxn];//row[i][j]表示 i,j左边障碍数;col 上边
struct step{
int x,y;
char direct;
}chase[maxt];
int m,n;
int ans;
int trip;
int found;
void load(){
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin>>field[i][j];
row[i][j]=row[i][j-1]+field[i][j];
col[j][i]=col[j-1][i]+field[j][i];
}
}
trip=0;
int from,to;
char dire;
while(cin>>from>>to>>dire) {
chase[trip].x=from;
chase[trip].y=to;
chase[trip].direct=dire;
++trip;
}
}
void search(int step,int x,int y){
if(found)return;
if(step==trip){
ans++;
found=1;
return;
}
for(int i=chase[step].x;i<=chase[step].y;++i){
int x0=x;int y0=y;
switch(chase[step].direct){//对当前点进行移位;
case 'R':y0+=i;break;
case 'L':y0-=i;break;
case 'U':x0-=i;break;
case 'D':x0+=1;break;
}
if(x0>=1&&x0<=m&&y0>=1&&y0<=n){//位置合法,开始判断移位是否合理,即移位前后两点之间是否有
switch(chase[step].direct){
case 'R':
case 'L':if(row[x0][max(y,y0)]==row[x0][min(y0,y)-1])search(step+1,x0,y0);break;//合法并进行下一步搜索
case 'U':
case 'D':if(row[max(x,x0)][y0]==row[min(x0,x)-1][x0])search(step+1,x0,y0);break;//合法并进行下一步搜索
}
}
}
}
int main(int argc, char** argv) {
memset(row,0,sizeof(row));
memset(col,0,sizeof(col));
int icase;
cin>>icase;
while(icase--){
load();
ans=0;
for(int j=1;j<=m;j++)
for(int i=1;i<=n;i++)
if(!field[j][i]){
found=0;
search(0,j,i);
}
cout<<ans;
}
return 0;
}