【牛客網】 發郵件 && 字符串計數
題目一:發郵件
題目描述:
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; //計算兩者之間的差距
}
}