可能是太久没做题了,没信心,起初看到这道题,差点就归为不会的类型放弃了。
后面耐心的看,思考了会,好像不难,第一反应就是用递归(一条路走到黑的)思路做,输入测试样例,好像对了 信心满满的提交。
import java.util.Scanner;
public class Main {
static long count = 0;
static int bx;
static int by;
static int n;
static int m;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
bx = input.nextInt();
by = input.nextInt();
n = input.nextInt();
m = input.nextInt();
dp(0, 0);
System.out.println(count);
}
public static void dp(int x, int y) {
// 找到了一条路,count+1;
if (x == bx && y == by) {
count++;
return;
}
//超过边界的情况
if (x > bx || y > by) {
return;
}
//马挡路的情况。
if (((x == n + 1 || x == n - 1) && (y == m + 2 || y == m - 2)) || ((x == n + 2 || x == n - 2) && (y == m + 1 || y == m - 1)) || (x == n && y == m)) {
return;
}
dp(x, y + 1);//向下走,
dp(x + 1, y);//向右走。
}
}
看到超时,又想不到哪里可以优化了,就想着,拿出王牌(转用c语言提交),可结果还是一样的,该超时的还是超时了,不死心的下载了他的样例,样例输入为“20 20 4 0”,试了一下自己的程序,好东西,要过这个样例,起码得上个小时,时间能过才怪。
没办法,只能推翻自己原先的思路,冥思(看了一下大神的思路)。
因为题意告诉我们了,只能向下走和向右走。所以反过来,我们要到达那个点,只能依靠那个点的上点和左点到达。
那么我们到达这个点可能的路径条数,就是上一个点和左边一个点的路径条数相加。
即:
1 1 1 1 1 1 1
1 2 X 1 X 1 2
1 X 0 1 1 X 2
1 1 1 M 1 1 3
1 X 1 1 0 X 3
1 1 X 1 X 0 3
1 2 2 3 3 3 6
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//终点横纵坐标。
int bx = input.nextInt();
int by = input.nextInt();
//马的横纵坐标。
int n = input.nextInt();
int m = input.nextInt();
long[][] chess = new long[bx + 2][by + 2];
//第一行和第一列舍弃,加上他本身,所以我们范围要加2.
chess[1][0] = 1;
// 也可以是chess[0][1] = 1;
// 但不能是chess[1][1]=1;因为那样会在循环里面被覆盖成0。
for (int i = 1; i < bx + 2; i++) {
for (int j = 1; j < by + 2; j++) {
//判断,如果有马挡路的情况,则跳过。
//因为我们第一行和第一列舍弃,所以我们马的横纵坐标都得加一。
if (judge(i, j, n + 1, m + 1)) {
continue;
}
//如果没有挡路,则到达这个点的路径条数,就是上一个点与左一个点的路径条数相加。
chess[i][j] = chess[i - 1][j] + chess[i][j - 1];
}
}
//打印最后一个数,即终点数,该数就是能到达终点的路径条数
System.out.println(chess[bx + 1][by + 1]);
}
//判断马挡路的情况
//1.x=n+1; y=m+2
//2.x=n+1; y=m-2
//3.x=n-1; y=m+2
//4.x=n-1; y=m-2
//5.x=n+2; y=m+1
//6.x=n+2; y=m-1
//7.x=n-2; y=m+1
//8.x=n-2; y=m-1
//9.x=n; y=m
public static boolean judge(int x, int y, int n, int m) {
if (((x == n + 1 || x == n - 1) && (y == m + 2 || y == m - 2)) || ((x == n + 2 || x == n - 2) && (y == m + 1 || y == m - 1)) || (x == n && y == m)) {
return true;
}
return false;
}
}
再一次的领会了算法的强大。