【牛客网】 发邮件 && 字符串计数
题目一:发邮件
题目描述:
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; //计算两者之间的差距
}
}