Description
丽萨参加了一个攀岩比赛,她想知道从起点到终点有多少种走法。
现在给你岩壁图,用1和0表示,其中1表示岩壁的那一处突出一块大石头,
丽萨没办法从那里通过,0表示能够顺利爬过去。
丽萨只能往左爬或往上爬。
起点是在最右下角的岩壁旁的地面,丽萨只能从最右下角开始往岩壁上爬,终点是在最左上角的岩壁。
你现在需要写出一个程序统计出丽萨有多少种走法。
Input
第一行整数m和n,分别表示岩壁图的行数和列数,m和n的值均不超过100;
后面m行每行n个整数;
Output
一个整数,表示有多少种走法
Sample Input
3 5
0 0 0 0 0
0 0 1 0 0
0 0 0 0 0
Sample Output
6
题解:
#include<iostream>
#include<vector>
using namespace std;
int m,n;
long long int uniquePathsWithObstacles(vector<vector<int > >&maps){//这里返回值用long long int 类型是考虑到理想状态的最大值是很大的
if(maps[0][0]==1)return 0;//当山顶位置是岩石时没有路径可走
if(maps.size()==1&&maps[0].size()==1){
if(maps[0][0]==1)return 0; //当山顶与山地重合时进行判断其实没有这步也行下面的运算包含这一步运算
else return 1;
}
vector<vector<long long int > >ans(m,vector<long long int >(n,0));//有相当于建立的一个m行n列的二维数组且每个元素的类型都是long long int 型
//注意建立里面的一维数组应该是vector<long long int>(n,0)
//ans我认为的是记录从山顶往山地走的过程中每个点可以走的可能数
//由题意得从山顶只能向右或向下走
//所以有通式ans[i][j]=ans[i-1][j]+ans[i][j-1]
ans[0][0]=1;//初始化山顶的可能数是1
//还要特殊考虑的是该二维数组都是从0行0列开始的即有0行0列的
//但0行0列是不符合上面的通式的
//所以单独考虑
for(int i=0;i<m;i++){ //初始化第0列
if(maps[i][0]==1)break; //该语句的意思是在遇到以此岩石后下面的未知的 可能数都是1 了
ans[i][0]=1;
}
for(int i=0;i<n;i++){
if(maps[0][i]==1)break;
ans[0][i]=1; //与上面语句类似
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(maps[i][j]==0)ans[i][j]=ans[i-1][j]+ans[i][j-1];//当该位置不是岩石时运行通式
//否则可能不变即保持原来的0
}
}
return ans[m-1][n-1];//返回最后位置的可能数
}
int main(){
cin>>m;
cin>>n;
vector<vector<int > >maps;//相当于建立了一个二维数组
vector<int >temp;//相当于建立了一个一维数组
for(int i=0;i<m;i++){
for(int j=0;j<n;j++)
{int k;
cin>>k;
temp.push_back(k); //给一维数组赋值
}
maps.push_back(temp);//给二维数组赋值
temp.clear(); //每次给二维数组赋值完成以后清空一维数组
}
cout<<uniquePathsWithObstacles(maps);
return 0;
}