题目描述
给定一个 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;
}
欢迎留言点赞
嗷嗷嗷