一、Acwing 4181 数的划分
将整数 n 分成 k 份,且每份不能为空,问有多少种不同的分法。
当 n=7,k=3 时,下面三种分法被认为是相同的:(1,1,5),(1,5,1),(5,1,1)(1,1,5),(1,5,1),(5,1,1)。
输入格式
一行两个整数 n,k。
输出格式
一行一个整数,即不同的分法数。
数据范围
6≤n≤200
2≤k≤6
输入样例:
7 3
输出样例:
4
样例解释
四种分法如下:(1,1,5),(1,2,4),(1,3,3),(2,2,3)(1,1,5),(1,2,4),(1,3,3),(2,2,3)。
代码
import java.io.*;
import java.util.*;
class Main {
static int N = 210;
static int K = 10;
static int n,k,res;
static int[] num = new int[K];
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
n = Integer.parseInt(input[0]); //7
k = Integer.parseInt(input[1]); //3
dfs(1,1,0);
System.out.print(res);
}
public static void dfs(int x,int start,int curSum) {
if(curSum > n) return;
if(x > k) {
if(curSum == n) {
res++;
}
return;
}
for(int i = start;curSum + (k - x + 1) * i <= n;i++) {
num[x] = i;
curSum += i;
dfs(x + 1,i,curSum);
curSum -= i;
num[x] = 0;
}
}
}
二、走迷宫
给定一个 n×m的二维整数数组,用来表示一个迷宫,数组中只包含 00 或 11,其中 00 表示可以走的路,11 表示不可通过的墙壁。
最初,有一个人位于左上角 (1,1)(1,1) 处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角 (n,m)) 处,至少需要移动多少次。
数据保证 (1,1)(1,1) 处和 (n,m)) 处的数字为 00,且一定至少存在一条通路。
输入格式
第一行包含两个整数 n 和 m。
接下来 n 行,每行包含 m 个整数(00 或 11),表示完整的二维数组迷宫。
输出格式
输出一个整数,表示从左上角移动至右下角的最少移动次数。
数据范围
1≤n,m≤100
输入样例:
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出样例:
8
用dfs超时的代码
import java.io.*;
import java.util.*;
class Main {
static int N = 110;
static int n,m;
static int res = Integer.MAX_VALUE;
static int[] dx = {1,0,-1,0};
static int[] dy = {0,1,0,-1};
static char[][] path = new char[N][N];
static boolean[][] st = new boolean[N][N];
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
n = Integer.parseInt(input[0]);
m = Integer.parseInt(input[1]);
for(int i = 0;i < n;i++) {
String[] line = br.readLine().split(" ");
for(int j = 0;j < m;j++) {
path[i][j] = line[j].charAt(0);
}
}
dfs(0,0,0);
System.out.print(res);
}
public static void dfs(int x,int y,int count) {
if(x == n - 1 && y == m - 1) {
res = Math.min(res,count);
return;
}
for(int i = 0;i < 4;i++) {
int a = x + dx[i];
int b = y + dy[i];
if(a < 0 || a >= n || b < 0 || b >= m) continue;
if(path[a][b] == '1') continue;
if(st[a][b]) continue;
st[a][b] = true;
dfs(a,b,count + 1);
st[a][b] = false;
}
}
}
后续还会用bfs优化代码
import java.io.*;
import java.util.*;
class Main {
static int n,m;
static int N = 110;
static int[][] p = new int[N][N];
static int[][] dist = new int[N][N];
static int[] dx = {1,0,-1,0};
static int[] dy = {0,1,0,-1};
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
n = Integer.parseInt(input[0]);
m = Integer.parseInt(input[1]);
for(int i = 1;i <= n;i++) {
String[] input1 = br.readLine().split(" ");
for(int j = 1;j <= m;j++) {
p[i][j] = Integer.parseInt(input1[j - 1]);
}
}
System.out.print(bfs(1,1));
}
public static int bfs(int x,int y) {
Queue<PII> q = new LinkedList<>();
for(int i = 0;i < N;i++) {
for(int j = 0;j < N;j++) {
dist[i][j] = -1;
}
}
dist[x][y] = 0;
q.add(new PII(1,1));
while(!q.isEmpty()) {
PII t = q.poll();
for(int i = 0;i < 4;i++) {
int a = t.first + dx[i];
int b = t.second + dy[i];
if(a <= 0 || a > n || b <= 0 || b > m) continue;
if(p[a][b] == 1) continue;
if(dist[a][b] > 0) continue;
dist[a][b] = dist[t.first][t.second] + 1;
q.add(new PII(a,b));
if(a == n && b == m) return dist[n][m];
}
}
return -1;
}
}
class PII {
public int first;
public int second;
public PII(int first,int second) {
this.first = first;
this.second = second;
}
}