先初始化n=1时,输出的图案。
观察可以得到,n每加1,则在原先图案的左下方和右下方重新打印一遍原先的图案,可以分为两步。
1.复制原先图案打印在其正下方和右下方,并将原先图案清空。
2.在现在图案的上方中间打印原先图案。
通过以上两步就完成了n+1时图案的复制。
需要注意对于数组要将其初始化为空,否则会报错。
#include <stdio.h>
#include<string.h>
int n,h=2,w=4;
char a[1030][2050];
int main() {scanf("%d", &n);memset(a, ' ', sizeof(a));a[1][1] = a[1][4] = ' ';a[1][2] = a[2][1] = '/';a[1][3] = a[2][4] = '\\';a[2][2] = a[2][3] = '_';for (int i = 1; i < n; i++) {for (int j = 1; j <= h; j++) {for (int k = 1; k <= w; k++) {a[j + h][k] = a[j + h][k + w] = a[j][k];a[j][k] = ' ';}}for (int j = 1; j <= h; j++) {for (int k = 1; k <= w; k++) {a[j][k+w/2] = a[j + h][k];}}h *= 2, w *= 2;}for (int j = 1; j <= h; j++) {for (int k = 1; k <= w; k++) {printf("%c", a[j][k]);}printf("\n");}return 0;
}
用一个数组来记录啊a,b,c位于0到20之间时,值的大小。
递归函数w每次调用,对于他每种递归的w,检测是否在数组中储存,若没有储存,则将其存入数组,从而实现记忆化搜索。
注意要开long long
#include<stdio.h>
#include<string.h>
#define LL long long
LL f[21][21][21];
LL w(LL a, LL b, LL c)
{if (a <= 0 || b <= 0 || c <= 0)return 1;if (a > 20 || b > 20 || c > 20)return w(20, 20, 20);if (a < b && b < c) {if (f[a][b - 1][c] == 0)f[a][b - 1][c] = w(a, b-1, c);if(f[a][b - 1][c-1] == 0)f[a][b - 1][c-1] = w(a, b-1, c-1);if (f[a][b][c - 1] == 0)f[a][b][c - 1] = w(a, b, c - 1);f[a][b][c] = f[a][b][c - 1] + f[a][b - 1][c - 1] - f[a][b - 1][c];}else {if (f[a-1][b][c] == 0)f[a-1][b][c] = w(a-1, b, c);if (f[a - 1][b-1][c] == 0)f[a - 1][b-1][c] = w(a - 1, b-1, c);if (f[a - 1][b][c-1] == 0)f[a - 1][b][c-1] = w(a - 1, b, c-1);if (f[a - 1][b-1][c-1] == 0)f[a - 1][b-1][c-1] = w(a - 1, b-1, c-1);f[a][b][c] = f[a - 1][b][c] + f[a - 1][b - 1][c] + f[a - 1][b][c - 1] - f[a - 1][b - 1][c - 1];}return f[a][b][c];
}
int main()
{LL a, b, c;while (1){scanf("%lld %lld %lld", &a, &b, &c);if (a == -1 && b == -1 && c == -1)return 0;printf("w(%lld, %lld, %lld) = %lld\n", a, b, c,w(a,b,c));}
}