前言
這道題理解起來不難,但是要找到乙個合適的方法對題目進行優化,就會相對麻煩些。
藍橋杯的題,真的到處都是坑的感覺。。。
資源限制
時間限制:1.0s 記憶體限制:256.0mb
問題描述
100 可以表示為帶分數的形式:100 = 3 + 69258 / 714。
還可以表示為:100 = 82 + 3546 / 197。
注意特徵:帶分數中,數字1~9分別出現且只出現一次(不包含0)。
類似這樣的帶分數,100 有 11 種表示法。
輸入格式
從標準輸入讀入乙個正整數n (n<1000*1000)
輸出格式
程式輸出該數字用數碼1~9不重複不遺漏地組成帶分數表示的全部種數。
注意:不要求輸出每個表示,只統計有多少表示法!
樣例輸入1
100樣例輸出1
11樣例輸入2
105樣例輸出2
6題目分析
①、帶分數中,數字1~9分別出現且只出現一次(不包含0)。
②、100 可以表示為帶分數的形式:100 = 3 + 69258 / 714。
解題思路
實用工具功能及使用
實現全排列:next_permutation(s.begin(), s.end());
在c++中,在字串要有序的前提下,我們能使用現成的函式完成字串的全排列。例如:string s=「123456789」;,字串s已經有序。通過 while(next_permutation(s.begin(), s.end())); 不斷將s進行全排序,當s的全排序全部排完後,跳出迴圈。可能你會覺得這個有什麼用?讓我們帶著這個問題看看**設計吧!
string s=
"123456789";do
while
(next_permutation
(s.begin()
, s.
end())
);
我們這裡用do-while的迴圈體,保證s每進行一次全排列就會先進行do包含的語句。
實現字串擷取:string a = s.substr(i,len);
在s字串中,從下標為i的位置,向右擷取len長度的字串,得到a字串。
實現字串轉換為int型別變數:int a = atoi(s.c_str);
將字串s轉換為int型別變數a。
**實現
**一通過我們的解題思路和工具結合,我們可以得到以下**一。
//全排列 next_permutation(s.begin(),s.end())
#include
#include
using namespace std;
#define ll long long
ll ans=0;
intmain()
}}//使用next_permutation前要先排序
while
(next_permutation
(s.begin()
, s.
end())
);cout<
// finish = clock();
// double _time = (double)(finish - start) / clocks_per_sec;
// printf("\ntime:%llf", _time);
return0;
}
好啦,恭喜你答對了題目一半,為什麼是一半呢?因為如果你拿去評測的話, 你會發現:執行超時!
下面是**二在n=100條件下的執行時間time (單位秒)
原因:substr函式返回的是值(而不是引用或指標) 在多次呼叫中傳遞了大量物件(而不是引用或指標) 導致了耗時多。
在**裡,substr函式被放在內層迴圈中,被呼叫的次數很多,這樣的對程式執行總時間的影響就增大了,拖慢了程式執行速度。
**二(手寫擷取字串,引用字串s)
#include
#include
using namespace std;
#define ll long long
ll ans=0;
intparse
(string &s,
int a,
int b)
//字串轉換為int型別
return temp;
}int
main()
}}}while
(next_permutation
(s.begin()
, s.
end())
);cout<
// finish = clock();
// double _time = (double)(finish - start) / clocks_per_sec;
// printf("\ntime:%llf", _time);
return0;
}
優化:擷取字串函式傳參採用傳指標或引用(即在parse 的string引數右側加乙個&)。
下面是**二在n=100條件下的執行時間time (單位秒)
時間上滿足1s內,可以通過評測。
下面還能夠再通過優化演算法的方式,進一步縮短執行時間。
**三(演算法優化)
#include
#include
using namespace std;
#define ll long long
ll ans=0;
intparse
(string& s,
int a,
int b)
//字串轉換為int型別
return temp;
}int
main()
}}}while
(next_permutation
(s.begin()
, s.
end())
);cout<
// finish = clock();
// double _time = (double)(finish - start) / clocks_per_sec;
// printf("\ntime:%llf", _time);
return0;
}
優化:排除多餘判斷情況。
下面是**三在n=100條件下的執行時間time(單位秒)
總結這道題思路固然重要,但是優化也很重要。
在藍橋杯的比賽中,都是提交**,我們不能都提前判斷我們的**是否能夠通過所有評測資料,所以要盡量將時間複雜度降到最小。
希望能夠將自己的一些學習經驗分享給有需要的人。
我是小鄭,乙個堅持不懈的小白。
帶分數 全排列
100 可以表示為帶分數的形式 100 3 69258714 還可以表示為 100 82 3546197 類似這樣的帶分數,100 有 11 種表示法。輸入格式 乙個正整數。輸出格式 輸出輸入數字用數碼 1 9 不重複不遺漏地組成帶分數表示的全部種數。資料範圍 1 n 106 輸入樣例1 100輸出...
藍橋帶分數(全排列)
100 可以表示為帶分數的形式 100 3 69258 714 還可以表示為 100 82 3546 197 注意特徵 帶分數中,數字1 9分別出現且只出現一次 不包含0 類似這樣的帶分數,100 有 11 種表示法。題目要求 從標準輸入讀入乙個正整數n n 1000 1000 程式輸出該數字用數碼...
帶分數(全排列 判斷條件)
100 可以表示為帶分數的形式 100 3 69258 714 還可以表示為 100 82 3546 197 注意特徵 帶分數中,數字1 9分別出現且只出現一次 不包含0 類似這樣的帶分數,100 有 11 種表示法。題目要求 從標準輸入讀入乙個正整數n n 1000 1000 程式輸出該數字用數碼...