不同路径数

题目描述
给定一个 n×m 的二维矩阵,其中的每个元素都是一个 [1,9] 之间的正整数。

从矩阵中的任意位置出发,每次可以沿上下左右四个方向前进一步,走过的位置可以重复走。

走了 k 次后,经过的元素会构成一个 (k+1) 位数。

请求出一共可以走出多少个不同的 (k+1) 位数。

输入格式
第一行包含三个整数 n,m,k。

接下来 n 行,每行包含 m 个空格隔开的整数,表示给定矩阵。

输出格式
输出一个整数,表示可以走出的不同 (k+1) 位数的个数。

数据范围
对于 30% 的数据, 1≤n,m≤2,0≤k≤2
对于 100% 的数据,1≤n,m≤5,0≤k≤5,m×n>1

样例
输入样例:
3 3 2
1 1 1
1 1 1
2 1 1
输出样例:
5
样例解释
一共有 5 种可能的 3 位数:

111
112
121
211
212

算法1 dfs
(暴力枚举) O(n^2)
搜索没什么好说的

时间复杂度
参考文献
C++ 代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100;
int n,m,k;
char g[N][N];
int dy[]={0,1,0,-1},dx[]={-1,0,1,0};
unordered_map<string, int> h;
void dfs(int x,int y,int u,string num)
{
    if(u>k)
    {
        h[num]=1;
        return ;
    }
    for(int i=0;i<4;i++)
    {
        int a=x+dx[i],b=y+dy[i];
        if(a>=1&&a<=n&&b>=1&&b<=m)
        {
            dfs(a,b,u+1,num+g[a][b]);
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i = 1; i <= n; i ++)
      for(int j =1; j <= m; j ++)
        cin>>g[i][j];
    string ans; 
    for(int i = 1; i <= n; i ++)
      for(int j =1; j <= m; j ++)
         dfs(i,j,0,ans);
    return cout<<h.size(),0;
}

Java代码

import java.util.*;
import java.io.*;
public class Main{
    static int n,m,k;
    static int[][] g=new int[10][10];
    static int[] dx={-1,0,1,0},dy={0,1,0,-1};
    static Set<Integer> set=new HashSet<>();
    public static void main(String[] args){
        Scanner cin = new Scanner(System.in);
        n=cin.nextInt();
        m=cin.nextInt();
        k=cin.nextInt();
        for(int i = 1; i <= n; i ++)
          for(int j =1; j <= m; j ++)
             g[i][j]=cin.nextInt();
        for(int i = 1; i <= n; i ++)
          for(int j =1; j <= m; j ++)
             dfs(i,j,1,g[i][j]);
         System.out.println(set.size());
    }
    static void dfs(int x,int y,int u,int num)
    {
        if(u>k)
        {
            set.add(num);
            return ;
        }
         for(int i=0;i<4;i++)
         {
           int a=x+dx[i],b=y+dy[i];
           if(a>=1&&a<=n&&b>=1&&b<=m)
            dfs(a,b,u+1,num*10+g[a][b]);
         }
    }
}

GO代码

package main

import "fmt"

const N = 20
var g[N][N] int    
var n,m,k int
var s map[int]bool
func dfs(x,y,k,u int){
    if k==0{
        u=u*10+g[x][y];
        if s[u]==false{
        s[u]=true;
        }
        return 
    }
    dy:=[]int{0,1,0,-1};
    dx:=[]int{-1,0,1,0};
    for i:= 0;i < 4; i ++ {
        a,b := x + dx[i],y + dy[i]
        if a >= 1 && b >= 1 && a <= n && b <= m{
            dfs(a,b,k-1,u*10+g[x][y])
        }
    }
}
func main(){
    s = make(map[int]bool)
    fmt.Scanf("%d %d %d",&n,&m,&k)
    for i:= 1;i <= n;i ++{
        for j := 1;j <= m;j ++{
            fmt.Scanf("%d",&g[i][j])
        }
    }
    for i:= 1;i <= n;i ++{
        for j := 1;j <= m;j ++{
            dfs(i,j,k,0)
        }
    }
    fmt.Println(len(s))
}


算法2 bfs
(暴力枚举) O(n^2)
时间复杂度
参考文献
C++ 代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <unordered_set>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
unordered_set <int> st;
const int N = 100;
int n,m,k;
int w[10][10];
int dy[]={0,1,0,-1},dx[]={-1,0,1,0};
void bfs(int x,int y)
{
    queue<pair<PII,int>>q;
    q.push({{x,y},w[x][y]});
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            int a=t.x.x+dx[i],b=t.x.y+dy[i];
            if(a>=1&&a<=n&&b>=1&&b<=m)
            {
            if(t.y*10+w[a][b]>pow(10,k))
            st.insert(t.y*10+w[a][b]);
            else q.push({{a,b},t.y*10+w[a][b]});
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i = 1; i <= n; i ++)
      for(int j =1; j <= m; j ++)
        cin>>w[i][j];
    for(int i = 1; i <= n; i ++)
      for(int j =1; j <= m; j ++)
         bfs(i,j);
    return cout<<st.size(),0;
}

欢迎留言点赞

嗷嗷嗷

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值