c语言每日一练-[字符串全排列][小股炒股][最小H值]

题目名称:字符串全排列

题目描述

对K个不同字符的全排列组成的数组, 面试官从中随机拿走了一个, 剩下的数组作为输入, 请帮忙找出这个被拿走的字符串? 比如[“ABC”, “ACB”, “BAC”, “CAB”, “CBA”] 返回 “BCA”

输入描述:

第一行输入整数n,表示给定n个字符串。(n == x!-1,2<=x<=10) 以下n行每行输入一个字符串。

输出描述:

输出全排列缺少的字符串。

示例

输入

5
ABC
ACB
BAC
CAB
CBA

输出

BCA

扫描二维码关注公众号,回复: 17346333 查看本文章

分析

1.第一个问题:因为输入时输入了当前输入的元素个数,以及缺失了部分元素的部分全排列元素。所以我们首先要考虑如何获得全排列元素,通过定义一个permute函数嵌套调用实现;

2.第二个问题:全排列元素已经获得,那怎么确定哪个元素缺失了。我通过遍历全排列元素,如果当前元素用户已经输入,则直接跳转到下一个元素,如果当前元素遍历了用户输入的元素后仍然没找到,则打印出来。

带着这两个核心思想,我的代码实现如下

代码示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void swap(char *x, char *y) {
    char temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

//计算出全排列所有元素,并判断全排列中哪个元素未出现过
void permute(char *a, int l, int length, int n, char **arr) {
    int i;

    // l = length时,说明是一个完整的排列元素,继续进行处理
    if (l == length) {
        int count = 0;
        for (int j = 0; j < n; j++) {
            if (strstr(arr[j], a) == NULL) {
                count++;
            } else {
                //一旦找到元素,则不需要再遍历了,直接return
                return;
        }
        // 遍历arr后仍然未找到当前全排列中的某个元素,打印出来
        if (count)
            printf("%s\n", a);
    } else {
        for (i = l; i < length; i++) {
            swap((a+l), (a+i));
            permute(a, l+1, length, n, arr);
            swap((a+l), (a+i)); // backtrack
        }
    }
}

void solution(int n, char **arr){
    int length = strlen(arr[0]);
    char str[length];
    memcpy(str, arr[0], sizeof(arr[0]));
    permute(str, 0, length, n, arr);
}

int main() {
    int n;
    scanf("%d", &n);

    char** arr;
    arr = (char**)malloc(n * sizeof(char*));
    for (int i = 0; i < n; i++){
        arr[i] = (char*)malloc(sizeof(char));
    }

    for (int i = 0; i < n; i++)
    {
        scanf("%s", arr[i]);
    }

    solution(n, arr);

    return 0;
}

题目名称:小股炒股

题目描述

已知n天后的股票行情,现在已有的本金是m, 规定只能入手一次股票和抛售一次股票。 最大收益是?

输入描述:

第一行输入整数n,m。(1<=n<=1000,1<=m<=10000) 第二行输入n个整数表示某股票单股价格p。(1<=p<=1000)

输出描述:

输出小最大收益

示例

输入

2 4
3 7

输出

8

分析

这题其实没什么可说的,没什么难度。题目也很友好地把难度降低了:只能买、卖一次。所以只要遍历行情列表,通过比较不同买入点和卖出点的收益,找出最大收益时的买点和卖点即可,时间复杂度是。必定存在更优化的方案,但在比赛的时候来不及细想,我记得题目提示了,所以穷举完全可以pass。

要注意的是,因为卖出的时间点必在买入之后,所以内循环只要从买入那天的隔天开始,到最后一天结束即可。

代码示例

#include <stdio.h>
#include <stdlib.h>

void solution(int n, int m, int *plist){
    int max_profit = 0;
    for (int i = 0; i < n; i++) {
        int buy = plist[i];
        for (int j = i + 1; j < n; j++) {
            int sell = plist[j];
            if (sell > buy) {
                int profit = (m / buy) * sell + m % buy;
                if (profit > max_profit)
                    max_profit = profit;
            }
        }
    }
    printf("%d\n", max_profit);
}

int main() {
    int tem_arr[2];
    
    for (int i = 0; i < 2; i++)
    {
        scanf("%d", &tem_arr[i]);
    }
    
    int n = tem_arr[0];
    int m = tem_arr[1];

    int* plist;
    plist = (int*)malloc(n * sizeof(int));

    for (int i = 0; i < n; i++)
    {
        scanf("%d", &plist[i]);
    }
    solution(n, m, plist);

    return 0;
}

题目名称:最小H值

题目描述

给你一个二维 rows x columns 的地图 heights , 其中 heights[row][col] 表示格子 (row, col) 的高度。 一开始你在最左上角的格子 (0, 0) , 且你希望去最右下角的格子 (rows-1, columns-1) (注意下标从 0 开始编号)。 你每次可以往 上,下,左,右 四个方向之一移动,你想要找到H值最小的一条路径。 一条路径的 H值 是路径上相邻格子之间 高度差绝对值 的 最大值 决定的。 请你返回从左上角走到右下角的最小H值。

输入描述:

输入:heights = [[1,2,2],[3,8,2],[5,3,5]]

输出描述:

输出:2 解释:路径 [1,3,5,3,5] 连续格子的差值绝对值最大为 2 。 这条路径比路径 [1,2,2,2,5] 更优,因为另一条路径差值最大值为 3 。

示例 

输入
 

* 输入样例1
```
[[1,2,2],[3,8,2],[5,3,5]]
```

* 输入样例2
```
`[[1,2,1,1,1],[1,2,1,2,1],[1,2,1,2,1],[1,2,1,2,1],[1,1,1,2,1]]`
```

输出

* 输出样例1

`2`


* 输出样例2

`0`

分析

这道题是考察图的问题,把每个格子都当作图的一个节点,相邻格子之间的差的绝对值当作边的权重,这样就可以把输入的矩阵转化成图的形式。

其中紫色表示的即为该图体力消耗最小的路径,消耗体力值为该路径的最大权重2
对于这道题我们可以采用并查集的做法,所以这道题就是求从最左上角的点到最右下角的点的连通性问题

首先,我们可以先把 图中所有的边都去掉,变成这个样子

然后添加权重最小的边0,发现添加完0边之后,没有连通起来,因此0不是最小体力消耗值,继续走

然后添加权重为1的边,发现还是没有连通起来,因此1也不是最小体力消耗值,然后添加权重为2的边,发现最左上角与最右下角连通起来了,因此2是最小体力消耗

在这道题中,并查集的作用就是判断最左上角的点和最右下角的点是否连通,同时在添加一条边时,如果该边的两个节点未连通,则将两个节点连通起来

代码示例

#include <stdio.h>  
#include <stdlib.h>  
#include <math.h>  
  
#define MAX_ROWS 100  
#define MAX_COLS 100  
  
int minH(int** heights, int rows, int columns) {  
    int dp[rows][columns];  
    for (int i = 0; i < rows; i++) {  
        for (int j = 0; j < columns; j++) {  
            if (i == 0 && j == 0) {  
                dp[i][j] = abs(heights[i][j] - heights[0][0]);  
            } else if (i == rows - 1 && j == columns - 1) {  
                dp[i][j] = 0;  
            } else {  
                dp[i][j] = INT_MAX;  
                if (i > 0) {  
                    dp[i][j] = min(dp[i][j], dp[i-1][j] + abs(heights[i][j] - heights[i-1][j]));  
                }  
                if (j > 0) {  
                    dp[i][j] = min(dp[i][j], dp[i][j-1] + abs(heights[i][j] - heights[i][j-1]));  
                }  
                if (i < rows - 1) {  
                    dp[i][j] = min(dp[i][j], dp[i+1][j] + abs(heights[i][j] - heights[i+1][j]));  
                }  
                if (j < columns - 1) {  
                    dp[i][j] = min(dp[i][j], dp[i][j+1] + abs(heights[i][j] - heights[i][j+1]));  
                }  
            }  
        }  
    }  
    return dp[0][0];  
}

猜你喜欢

转载自blog.csdn.net/tombaby_come/article/details/133904062