【牛客网】--- 发邮件 && 字符串计数

【牛客网】 发邮件 && 字符串计数

题目一:发邮件
题目描述
NowCoder每天要给很多人发邮件。有一天他发现发错了邮件,把发给A的邮件发给了B,把发给B的邮件发给了A。于是他就思考,要给n个人发邮件,在每个人仅收到1封邮件的情况下,有多少种情况是所有人都收到了错误的邮件?即没有人收到属于自己的邮件。

输入描述:
输入包含多组数据,每组数据包含一个正整数n(2≤n≤20)。

输出描述:
对应每一组数据,输出一个正整数,表示无人收到自己邮件的种数。

解题思路
还是探索动规的问题,最简单的方法还是先摸索一下能不能找到状态方程解决,在这里我们要知道,当n个编号元素放在n个编号位置,元素编号与位置编号各不对应的方法数用D(n)表示,那么D(n-1)就表示n-1个编号元素放在n-1个编号位置,各不对应的方法数,其它类推.
第一步,把第n个元素放在一个位置,比如位置k,一共有n-1种方法;
第二步,放编号为k的元素,这时有两种情况:

  • ⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;
  • ⑵第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法;

综上得到
状态方程:D(n) = (n-1) [D(n-2) + D(n-1)]
特殊情况:D(1) = 0, D(2) = 1

代码如下

#include<iostream>
using namespace std;

long int Failrecve(int n)
{
	if (n<2)
	{
		return 0;
	}
	if (n == 2)
	{
		return 1;
	}
	if (n == 3)
	{
		return 2;
	}
	return (n - 1)*(Failrecve(n - 1) + Failrecve(n - 2));
}

int main()
{
	int n;
	while (cin >> n)
	{
		cout << Failrecve(n) << endl;
	}
	return 0;
}

题目二:字符串计数
题目描述:求字典序在s1和s2之间的长度在len1和len2之间的字符串个数,结果为mod 10000007。

输入描述:每组数据包涵s1(长度小于100),s2(长度小于100),len1(小于100000),len2(大于len1,小于100000)。

解题思路:首先我们需要搞清楚的是字典序是什么意思?字典序即从两个字符串的下标为0开始进行对比,字典序是从左往右进行对比的。例如ab,abc这样两者之间的字符串个数为aba,abb,而ab、bb之间的字符串个数为ac,ad,ae,az,ba者26个,所以高位的字符串个数要是26的i次幂。在这里我们应该先求出字符串s1到字符串a之间差的字符串个数,再求出字符串s2到a相差的个数,然后两者想减之差就是字符串个数。

代码如下

#include<iostream>
#include<string>
using namespace std;

int Fun(string& s)
{
	int ret = 0;
	for (int i = 0; i<s.size(); ++i)
	{
		ret = ret * 26 + s[i] - 'a';  //从字符串a到这个字符串有多少个不同的字符串
	}
	return ret;
}

int main()
{
	string s1, s2;
	int l1, l2;
	while (cin >> s1 >> s2 >> l1 >> l2)
	{
		cout << (Fun(s2) - Fun(s1) - 1) % 1000007 << endl; //计算两者之间的差距
	}
}
发布了57 篇原创文章 · 获赞 301 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/L19002S/article/details/104848414
今日推荐