华为机试——软件开发机试真题2020.04.29
1.获取字符串排列组合数量
题目描述:
输入:字符串
输出:该字符串中的元素能够排列组合成的最多的数目 例如:输入abc,能够排列abc acb bac bca cab cba六种 输出:6
当然存在多组测试用例。
思路:1.存储字符数组总长度 2.每个字符出现的次数 3.字符串能够排列的组合数量=字符数量阶乘 / 每一个字母数量阶乘 如:abc能够排列的组合=3!/1!/1!/1!=6
#include<stdio.h> #include<string.h> int jieceng(int n) { int result=1; while (n) { result *= n; n--; } return result; } int main() { char str[100]; int len; scanf("%s", str); len = strlen(str); int arr[26] = { 0 };//存储字母 int i; int ID; for (i = 0; i < len; i++) { ID = str[i] - a; arr[ID]++; } int m=1; for (i = 0; i < len; i++) { if (arr[i] > 0) { m = m * jieceng(arr[i]); } } int result; result = jieceng(len) / m; printf("%d ", result); }
2.删除字母求字典序最小的字符串
删除字母求字典序最小的字符串。
输入 第一行代表字符串,第二行 k 代表要删除字母的个数,k 小于字符串长度。
输出字典序最小的字符串。
输入:
abacc 1
输出:
aacc
思路: 1.首先循环k次删k个字母,按照如下规则:每次循环比较相邻两个,前一个大就删除前一个,比如bca,就删除c 2.如果第m次没有删除 说明剩余的字母已从小到大排列,比如aabbcc,那直接从后往前删就行了。 3.对于剩余k-m次,直接删除后k-m个元素即可。
#include<stdio.h> #include<string.h> void delectChar(char* str,int n) { int len; len = strlen(str); for (int i = n; i < len; i++) { str[i] = str[i + 1]; } } int main() { char str[100]; int len; int k; scanf("%s", str); scanf("%d", &k); len = strlen(str); int m; int i,j; int len2 = len; int flag = 0; for (i = 0; i < k; i++) { for (j = 0; j < len - 1; j++) { if (str[j]>str[j + 1])//遍历数组,依次比较相邻元素的大小,如果前者大于后者,则删除前者 { delectChar(str, j); len--;//长度自减 break; } } m = i;//记录第i次删除 if (len == (len2 - i))//如果原数组长度-当前次数=当前数组长度, { flag = 1; break; } } if (flag) { for (i=m; i < k; i++)//还需要对当前str剩余值删k-m次 { delectChar(str, len-1);//对于每次返回的值,都删除第len-k个位置的元素 len--; } } printf("%s ", str); }
3. 约会城市最短路径 + 有限路费
题目大意:
k : 硬币数量
n:城市数量
r:城市道路数量
接下来输入 r 行,每一行有四个元素,第一个表示源城市 S,第二个表示目标城市 D , 第三个表示路径长度 L,第四个表示路费 C
求从 1 ~ n 的最短路径,并且能保证硬币足够。如果没有这样的路径那么输出 -1;
分析:
遍历所有道路,如果源城市与当前城市相同,那么就进行一次判定。 减去路费,目标城市变为源城市,路径长度变长。 递归下去
输入:
5 6 7 1 2 2 4 2 4 3 3 3 4 2 4 1 3 4 1 4 6 2 1 3 5 2 0 5 4 3 2
输出:
11
上一篇:
Java基础知识总结(2021版)