有一只地鼠不小心跑进了一个m*n的矩形田地里,假设地鼠在这块田地的初始位置为(x,y),并且每次只能向相邻的上下左右四个方向移动一步,那么在最多移动K次的情况下,有多少条路径可以逃出这片田地(一旦出去田地的边界就不能再往回走)?
下面是样例示意图:
输入数据包括五个参数:m,n,x,y,K
其中m和n的范围均为是[1,10],K的范围是[0,10]。
0<=x<m,0<=y<n。
输出成功逃跑的路径数量。
2 3 0 1 2
6
#include <bits/stdc++.h> using namespace std; int m, n, x, y, k, ans; int dx[] = {0, 1, -1, 0}; int dy[] = {1, 0, 0, -1}; bool outside(int x, int y) { return x < 0 || m <= x || y < 0 || n <= y; } void dfs(int x, int y, int k) { if (k <= 0) return; for (int i = 0; i < 4; ++i) { int nx = x + dx[i], ny = y + dy[i]; if (outside(nx, ny)) ++ans; else dfs(nx, ny, k - 1); } } int main() { scanf("%d %d %d %d %d", &m, &n, &x, &y, &k); dfs(x, y, k); cout << ans << endl; return 0; }
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { static int count = 0; static int[] dx = {-1, 1, 0, 0}; static int[] dy = {0, 0, -1, 1}; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int m = Integer.parseInt(br.readLine()); int n = Integer.parseInt(br.readLine()); int x = Integer.parseInt(br.readLine()); int y = Integer.parseInt(br.readLine()); int k = Integer.parseInt(br.readLine()); boolean[][] grid = new boolean[m][n]; dfs(grid, x, y, k); System.out.println(count); } private static void dfs(boolean[][] grid, int x, int y, int rest) { if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length){ if(rest >= 0){ count ++; // 合法逃出方案数自增 } }else{ if(rest > 0){ grid[x][y] = true; for(int i = 0; i < 4; i++){ dfs(grid, x + dx[i], y + dy[i], rest - 1); // 回溯 if(0 <= x + dx[i] && x + dx[i] < grid.length && 0 <= y + dy[i] && y + dy[i] < grid[0].length){ grid[x + dx[i]][y + dy[i]] = false; } } } } } }
这道题目就是一个dfs,同时没有说该地鼠走过的路不能再走了。
import java.io.BufferedReader; import java.io.InputStreamReader; public class Main{ static boolean[][] vis; static int count=0; public static void main(String[] args) throws Exception{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; str = br.readLine(); // 处理输入 String m=str.trim(); int m1=Integer.parseInt(m); str=br.readLine(); String n=str.trim(); int n1=Integer.parseInt(n); str=br.readLine(); String x=str.trim(); int x1=Integer.parseInt(x); str=br.readLine(); String y=str.trim(); int y1=Integer.parseInt(y); str=br.readLine(); String k=str.trim(); int k1=Integer.parseInt(k);// 需要用到的步数 int[][] arr=new int[m1][n1]; // 坐标为x1,y1; arr[x1][y1]=1; // vis[x1][y1]=true; dfs(arr,x1+1,y1,k1-1); dfs(arr,x1-1,y1,k1-1); dfs(arr,x1,y1+1,k1-1); dfs(arr,x1,y1-1,k1-1); System.out.println(count); } public static void dfs(int[][] arr,int i,int j,int step){ if(step<0) return; if((i<0||i>=arr.length||j<0||arr[0].length<=j) ){ if(step>=0){ count++; } return; } // if(arr[i][j]==1) return; // arr[i][j]=1; dfs(arr,i+1,j,step-1); dfs(arr,i-1,j,step-1); dfs(arr,i,j+1,step-1); dfs(arr,i,j-1,step-1); // arr[i][j]=0; } }
import java.util.Scanner; public class Main { public int countPath(int m, int n, int x, int y, int k) { if (!(x>=0 && x<m && y>=0 && y<n)) // 逃出 return 1; else if (k == 0) // 在范围内,但步数已经为0,返回0 return 0; return countPath(m,n,x+1,y,k-1) + countPath(m,n,x-1,y,k-1) + countPath(m,n,x,y+1,k-1) + countPath(m,n,x,y-1,k-1); } public static void main(String[] args) { Scanner in = new Scanner(System.in); Main main = new Main(); while(in.hasNextInt()) { int m = in.nextInt(); int n = in.nextInt(); int x = in.nextInt(); int y = in.nextInt(); int k = in.nextInt(); System.out.println(main.countPath(m,n,x,y,k)); } } } |
#include<bits/stdc++.h> using namespace std; int f(int m, int n, int x, int y, int k) { if (k==0 && x>=0&&x<m && y>=0&&y<n) { return 0; } // yuejie if (x<0 || x>=m || y<0 || y>=n) { return 1; } // k > 0 int ans = 0; ans += f(m, n, x-1, y, k-1); ans += f(m, n, x+1, y, k-1); ans += f(m, n, x, y-1, k-1); ans += f(m, n, x, y+1, k-1); return ans; } int main() { int m,n,x,y,k; cin>>m>>n>>x>>y>>k; cout << f(m,n,x,y,k) << endl; return 0; }
#include <iostream> #include <iomanip> #include <algorithm> #include <string> #include <list> #include <math.h> #include <set> #include <cstdio> #include <queue> #include <sstream> #include <stack> //#define DBL_MAX 1.7976931348623158e+308 using namespace std; typedef long long ll; #define BIG 1000000000 //习惯性带上上面 int f(int m, int n, int x, int y, int k) { if (x < 0 || y < 0 || x >= n || y >= m) { return 1; } if (k <= 0) { return 0; } return f(m, n, x + 1, y, k - 1) + f(m, n, x - 1, y, k - 1) + f(m, n, x, y + 1, k - 1) + f(m, n, x, y - 1, k - 1); } int main() { int m, n, x, y, k; cin >> m >> n >> y >> x >> k; cout << f(m, n, x, y, k) << endl; return 0; }
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner scan = new Scanner(System.in); int m = scan.nextInt(); int n = scan.nextInt(); int x = scan.nextInt(); int y = scan.nextInt(); int k = scan.nextInt(); boolean[][] flags = new boolean[m][n]; int res; res = helper(m, n, x, y, k, 0); System.out.println(res); scan.close(); } private static int helper(int m, int n, int x, int y, int k, int step) { int count = 0; // 如果超出了步数,那么直接返回0 if (k < step) return 0; // 已经在外边,那么直接返回 if (x < 0 || x >= m || y < 0 || y >= n){ return 1; } int up = helper(m, n, x - 1, y, k, step + 1); int down = helper(m, n, x + 1, y, k, step + 1); int left = helper(m, n, x, y - 1, k, step + 1); int right = helper(m, n, x, y + 1, k, step + 1); // 所有的数量为上下左右之和 count += (up + right + left + down); return count; } }
#include<iostream> using namespace std; int func(int x, int y,int K,int m,int n) { int up = 0, down = 0, left = 0, right = 0, sum = 0; if (K == 0) return 0; if (x==0)//向上 up = 1; else up = func(x - 1, y, K - 1, m, n); if (x == m - 1)//向下 down = 1; else down = func(x + 1, y, K - 1, m, n); if (y == 0)//向左 left = 1; else left = func(x, y - 1, K - 1, m, n); if (y == n - 1)//向右 right = 1; else right = func(x, y + 1, K - 1, m, n); sum = up + down + left + right; return sum; } int main() { int m = 0, n = 0, x = 0, y = 0, K = 0; cin >> m; cin >> n; cin >> x; cin >> y; cin >> K; cout << func(x, y, K, m, n); }
#include <iostream> using namespace std; int m,n,x,y,k,ans; void solve(int h,int i,int j){ if(h>k) //超过步数 return; else if(i>=m||i<0||j>=n||j<0) //走出田地范围 ans++; else{ solve(h+1,i-1,j); //上 solve(h+1,i+1,j); //下 solve(h+1,i,j-1); //左 solve(h+1,i,j+1); //右 } } int main(){ cin>>m>>n>>x>>y>>k; solve(0,x,y); cout<<ans; return 0; }
需要额外注意的是,上下左右是四种情形,不能合并处理。刚开始if合起来判断了,总是少一点
#include <iostream> #include <vector> #include <algorithm> using namespace std; int m, n, k; void times(int x, int y, int left_times, int &count) { if (left_times > 0) { if (x == 0 ) count++; if (x == m - 1) count++; if (y == 0 ) count++; if (y == n - 1) count++; if (x > 0) times(x - 1, y, left_times - 1, count); if (x < m - 1)times(x + 1, y, left_times - 1, count); if (y < n - 1) times(x, y + 1, left_times - 1, count); if (y > 0) times(x, y - 1, left_times - 1, count); } } int main() { cin >> m >> n; int x, y, count = 0; cin >> x >> y >> k; times(x, y, k, count); cout << count; system("pause"); return 0; }
"""" BFS或DFS """ import sys from collections import deque def BFS(m, n, x, y, K): deq = deque([(x, y, 0)]) ans = 0 while deq: i, j, k = deq.popleft() if k >= K: break if i + 1 >= m: ans += 1 else: deq.append((i + 1, j, k + 1)) if i - 1 < 0: ans += 1 else: deq.append((i - 1, j, k + 1)) if j + 1 >= n: ans += 1 else: deq.append((i, j + 1, k + 1)) if j - 1 < 0: ans += 1 else: deq.append((i, j - 1, k + 1)) return ans if __name__ == "__main__": # sys.stdin = open("input.txt", "r") m, n, x, y, K = int(input()), int(input()), int(input()), int(input()), int(input()), ans = BFS(m, n, x, y, K) print(ans)
其实就是计算第n步所有边界上的点的和。 矩阵进行k次转移,然后统计和即可。 转移方程直接用周围四个点转移。 #include<iostream> #include<algorithm> #include<cstring> #include<map> #include<bits/stdc++.h> using namespace std; int z[15][15]; int a[15][15]; int main() { // freopen("in","r",stdin); int m,n,x,y,k; cin>>n>>m>>x>>y>>k; x++; y++; z[x][y]=1; // k--; int sum=0; while(k--){ for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ a[i][j]=(z[i-1][j]+z[i+1][j]+z[i][j+1]+z[i][j-1]); if(i==1){ sum+=z[i][j]; } if(i==n){ sum+=z[i][j]; } if(j==1){ sum+=z[i][j]; } if(j==m){ sum+=z[i][j]; } } } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ z[i][j]=a[i][j]; // cout<<z[i][j]<<' '; } // cout<<endl; } } cout<<sum<<endl; return 0; }
很简单的DFS
当前坐标、步数对应的路径总数 = 当前方格能1步出田地的路径数 + 上下左右步数+1时出田地的路径数
#include
using namespace std;
int dfs(int i, int j, const int& row, const int& col, int step, const int& K){
int now = 0;
if(step==K) //K步之后还在田地里
return 0;
if(i==0)
++now;
if(j==0)
++now;
if(i==row-1)
++now;
if(j==col-1)
++now;
int up,down,left,right;
up = down = left = right = 0;
if(i>0)
up = dfs(i-1,j,row,col,step+1,K);
if(i<row-1)
down = dfs(i+1,j,row,col,step+1,K);
if(j>0)
left = dfs(i,j-1,row,col,step+1,K);
if(j<col-1)
right = dfs(i,j+1,row,col,step+1,K);
return now+up+down+left+right;
}
int main(){
int m,n,x,y,K;
cin>>m>>n>>x>>y>>K;
int result = dfs(x,y,m,n,0,K);
cout<<result<<endl;
return 0;
}
import java.util.Scanner; public class Main { static int m; static int n; static int K; public static void main(String[] args) { //输入数据包括五个参数:m,n,x,y,K Scanner scanner = new Scanner(System.in); m = scanner.nextInt(); n = scanner.nextInt(); int x = scanner.nextInt(); int y = scanner.nextInt(); K = scanner.nextInt(); System.out.println(fun(x,y,0)); } static int fun(int x,int y,int step){ if (step>K) return 0; if (x<0||y<0||x>=m||y>=n) return 1; return fun(x-1,y,step+1)+fun(x+1,y,step+1)+fun(x,y-1,step+1)+fun(x,y+1,step+1); } }
#include <bits/stdc++.h> using namespace std; int m,n,k; int DFS(int x, int y, int s){ int sum=0; if(s==k) return 0; if(x==0) sum++; if(y==0) sum++; if(x==m-1) sum++; if(y==n-1) sum++; if(x>0) sum += DFS(x-1,y,s+1); if(x<m-1) sum += DFS(x+1,y,s+1); if(y>0) sum += DFS(x,y-1,s+1); if(y<n-1) sum += DFS(x,y+1,s+1); return sum; } int main(){ int x,y; cin>>m>>n>>x>>y>>k; cout<<DFS(x,y,0)<<endl; return 0; }
package main import ( "fmt" ) func main() { var m,n,x,y,k int fmt.Scan(&m,&n,&x,&y,&k) ans:=0 var dfs func(int,int,int) dfs=func(i,j int,tot int){ if tot>k{ return } if (i<0||i>=m||j<0||j>=n)&&tot<=k{ ans++ return } tot++ dfs(i+1,j,tot) dfs(i-1,j,tot) dfs(i,j+1,tot) dfs(i,j-1,tot) } dfs(x,y,0) fmt.Print(ans) }
import sys # for line in sys.stdin: # a = line.split() # print(int(a[0]) + int(a[1])) para = [] for i in range(5): num = int(input()) para.append(num) row, col = para[0], para[1] start = (para[2], para[3]) K = para[-1] tian = [[0]*3 for _ in range(row)] res = [] temp = [] def func(start, K): global res, tian, temp m, n = start if ((m<0&nbs***bsp;m>=row)&nbs***bsp;(n<0&nbs***bsp;n>=col) and K>=0): res.append(temp.copy()) return K -= 1 if K<0: return temp.append(start) func((m+1, n), K) func((m-1, n), K) func((m, n-1), K) func((m, n+1), K) temp.pop() K += 1 func(start, K) print(len(res))