华为机试——软件开发机试真题2020.04.29

1.获取字符串排列组合数量

题目描述:

输入:字符串

输出:该字符串中的元素能够排列组合成的最多的数目

例如:输入abc,能够排列abc  acb  bac bca  cab cba六种

输出:6

当然存在多组测试用例。

思路:1.存储字符数组总长度

2.每个字符出现的次数

3.字符串能够排列的组合数量=字符数量阶乘 / 每一个字母数量阶乘

如:abc能够排列的组合=3!/1!/1!/1!=6

#include
#include

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\n", result);
}

2.删除字母求字典序最小的字符串

删除字母求字典序最小的字符串。

输入 第一行代表字符串,第二行 k 代表要删除字母的个数,k 小于字符串长度。

输出字典序最小的字符串。

输入:

abacc

1

输出:

aacc

 思路:

1.首先循环k次删k个字母,按照如下规则:每次循环比较相邻两个,前一个大就删除前一个,比如bca,就删除c

2.如果第m次没有删除 说明剩余的字母已从小到大排列,比如aabbcc,那直接从后往前删就行了。

3.对于剩余k-m次,直接删除后k-m个元素即可。

#include
#include

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\n", 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

 

你可能感兴趣的:(C/C++,华为笔试)