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