总结:递归 进制转换 高精度算法 依然不难 浅尝辄止 有些细节要注意
周任务二
一、迷宫(递归遍历)
题目描述:给定一个迷宫,迷宫中的每个位置都有一个非负整数值,代表通过该位置所需要消耗的体力值。从起点位置开始,每次只能向右或向下移动一步,找到一条从起点到终点的路径,使得路径上的体力消耗最小。请找出这条路径的体力消耗总和。
输入
1.矩阵的行x,列y(均小于100) 2.输入x行y列的二维数组
样例输入
3 3
1 3 1
1 5 1
4 2 1
输出
最小值。
样例输出
7
代码实现
#include<stdio.h>
#include<climits>
int minmg(int a[][100], int n, int k, int x, int y) {
int min = a[n][k];
int down = (n < x ? a[n + 1][k] : -1);//如果探出下边界则返回-1
int right = (k < y ? a[n][k + 1] : -1);//如果探出右边界则返回-1
//走到终点
if (n == x && k == y) {
return min;
}
//
//若探出边界则赋值为超大数(有些oj不认识INT_MAX,改成2147483647即可)
int minDown = (down == -1 ? INT_MAX : minmg(a, n + 1, k, x, y));
int minRight = (right == -1 ? INT_MAX : minmg(a, n, k + 1, x, y));
//挑选最短路径(若探出边界则一定大于另一条路)
return min + (minDown < minRight ? minDown : minRight);
//
}
//
int main()
{
//创建并储存迷宫
int x, y;
scanf("%d%d", &x, &y);
int i, j;
int a[100][100];
for (i = 0; i < x; i++) {
for (j = 0; j < y; j++) {
scanf("%d", &a[i][j]);
}
}
//
//打印结果
int result = minmg(a, 0, 0, x - 1, y - 1);
printf("%d\n", result);
//
return 0;
}
经验总结
递归
简单的递归练习 但递归本来就不简单...
二、小小进制(进制转换)
小明刚刚学完2、8、10、16进制的转换,觉得现在的自己已经学的非常好了,但是立马就被其他同学除了一道题10进制转其他进制的题,他信心满满的去做发现,转的不是2、8、16进制,而是2-36进制。 为了不被打脸,小明来找你帮忙,写出这样的程序。完成R进制的转换(2<=R<=36)
输入
输入两行,第一行包括10进制准备转的正整数N,第二行包括一个正整数R,保证1<=N<=10^10
样例输入
123
25
输出
输出一行,为N的R进制表示
样例输出
4N
代码实现
void z(int n, int r) {
char base[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char result[100];
int n_t = n;
int m;
int i = 0;
while (n_t > 0) {
m = n_t % r;
result[i] = base[m];
n_t = n_t / r;
i++;
}
for (int j = i - 1; j >= 0; j--) {
printf("%c", result[j]);
}
}
int main() {
int n, r;
scanf("%d%d", &n, &r);
z(n, r);
return 0;
}
经验总结
进制转换
所有进制转换(36以下)都是以base基表转换的,基本逻辑就如代码中while那一段。
三、桃核换桃
森林里的规则是,可以用 numExchange 个桃核从超市兑换桃。最开始,小猴子一共购入了 numPeachs 个桃。
吃掉桃子,获得桃核。
请问小猴子最多可以吃到多少个桃子?
输入
输入两个整数分别代表 numPeachs 和 numExchange ,中间以空格隔开
1 <= numPeachs <= 100
2 <= numExchange <= 100
样例输入
9 3
输出
小猴子最多可以吃到多少个桃
样例输出
13
代码实现
int main()
{
//存储初始条件,P为桃子数量,E为交换条件量,i为吃掉的桃子数量
int P, E, i;
scanf("%d%d", &P, &E);
i = P;
//
//循环计算 直到桃核(桃子)不够交换
while (1) {
if (P >= E) {
i += (P / E);
P = P / E + P % E;
}
else
break;
}
//
printf("%d", i);
return 0;
}
经验总结
简单的模拟 模拟时不仅要还原人的思想 也要考虑到计算机的优势---快速计算
四、小学生计算题2.0(高精度算法)
mkk学长给大家出了一道小学生都会的简单计算题,问题是这样的,给出了A,B,C,D四个正整数,现在对他们进行简单的混合运算,运算格式是:“(A * B + C) - D ”,现在请你运算出结果(结果可能为负数)。
输入
四个正整数,0 <= A,C,D <= 1000000000000000000, 0 <= B <= 10000
样例输入
100 12 3 19
输出
一个整数
样例输出
1184
代码实现
#include<string.h>
//准备
#define LEN 1004
int a[LEN], b[LEN], c[LEN], d[LEN], rm[LEN], ra[LEN], rs[LEN];
void clear(int a[]) {
for (int i = 0; i < LEN; ++i)
a[i] = 0;
}
void read(int a[]) {
char s[LEN + 1];
scanf("%s", s);
clear(a);
int len = strlen(s);
for (int i = 0; i < len; ++i)
a[len - i - 1] = s[i] - '0';
}
void print(int a[]) {
int i;
for (i = LEN - 1; i >= 1; --i)
if (a[i] != 0)
break;
for (; i >= 0; --i)
putchar(a[i] + '0');
putchar('\n');
}
//
//加法
void add(int a[], int b[], int c[]) {
clear(c);
for (int i = 0; i < LEN - 1; ++i) {
c[i] += a[i] + b[i];
if (c[i] >= 10) {
c[i + 1] += 1;
c[i] -= 10;
}
}
}
//减法
void sub_base(int a[], int b[], int c[]) {
clear(c);
for (int i = 0; i < LEN - 1; ++i) {
c[i] += a[i] - b[i];
if (c[i] < 0) {
c[i + 1] -= 1;
c[i] += 10;
}
}
}
int flag = 0;
int swap_sub(int* a, int* b) {
for (int i = LEN-1; i >= 0; i--) {
if (a[i] > b[i]) {
return flag;
}
else if (a[i] < b[i]) {
return flag = 1;
}
}
return flag;
}
void sub_print(int a[],int b[],int c[]) {
swap_sub(a, b);
if (flag) {
sub_base(b, a, c);
putchar('-');
print(c);
}
else{
sub_base(a, b, c);
print(c);
}
}
//乘法
void mul(int a[], int b[], int c[]) {
clear(c);
for (int i = 0; i < LEN - 1; ++i) {
for (int j = 0; j <= i; ++j)
c[i] += a[j] * b[i - j];
if (c[i] >= 10) {
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
}
}
//
int main() {
read(a); read(b); read(c); read(d);
mul(a, b, rm);
add(rm, c, ra);
sub_print(ra, d, rs);
return 0;
}
经验总结
高精度算法
一开始上手会觉得很麻烦很难 核心逻辑理清楚了就很轻松了
加法
注意进位,最首位是否进位需不需要加长数组
减法
注意比较两数大小 若小减大先用大减小最后输出“-”即可
乘法
注意进位以及每位要逐位相乘。
每次运算前记得clear储存结果数组 若不想初始化就在外部静态创建数组(但还是要clear)