【牛客網】--- 發郵件 && 字符串計數

【牛客網】 發郵件 && 字符串計數

題目一:發郵件
題目描述
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; //計算兩者之間的差距
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章