2018 藍橋杯省賽 B 組模擬賽
阿新 • • 發佈:2019-05-04
最長 題意 eof oid 開頭 strlen const style for循環 相信大家都知道什麽是全排列,但是今天的全排列比你想象中的難一點。我們要找的是全排列中,排列結果互不相同的個數。比如:
D. 代碼填空:LIS
LIS是最長上升子序列。什麽是最長上升子序列? 就是給你一個序列,請你在其中求出一段最長嚴格上升的部分,它不一定要連續。
就像這樣:2, 3, 4, 7 和 2, 3, 4, 6 就是序列 2 5 3 4 1 7 6 的兩個上升子序列,最長的長度是 4。
#include<iostream> #include<cstring> using namespace std; int f[10000], b[10000]; int lis(int n) { memset(f, 0, sizeof f); int res = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < i; ++j) { if (b[j] < b[i]) { /*填入代碼*/ } } res = max(res, f[i]); } return res+1; } int main() { int n; scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d", b + i); } printf("%d\n", lis(n)); return 0; }
題目分析
動態規劃,lis經典模型,最基礎的O(n2)算法。填入f[i] = max(f[j] + 1,f[i]);
E.代碼填空:全排列
相信大家都知道什麽是全排列,但是今天的全排列比你想象中的難一點。我們要找的是全排列中,排列結果互不相同的個數。比如:aab
的全排列就只有三種,那就是aab
,baa
,aba
。
代碼框中的代碼是一種實現,請分析並填寫缺失的代碼。
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include<algorithm> using namespace std; const int N=1e3; char str[N], buf[N];//buffer int vis[N], total, len; void arrange(int num) { if (num == len){ printf("%s\n", buf); total++; return; } for (int i = 0; i < len; ++i) { if (!vis[i]) { int j; for (j = i + 1; j < len; ++j) { if (/*填入代碼*/) { break; } } if (j == len) { vis[i] = 1; buf[num] = str[i]; arrange(num + 1); vis[i] = 0; } } } } int main() { while (~scanf("%s",str)) { len = strlen(str); sort(str, str + len); total = 0; buf[len] = ‘\0‘; arrange(0); printf("Total %d\n", total); } return 0; }
題目分析
這個函數可以求出去重後的全排列。如果不填入代碼,輸入aab,則輸出aab aab aba aba baa baa。與題意不符,因此推斷,填入代碼所在的for循環是用來去重的。
第一個a作為第一個元素形成的序列有aab aba ,如果第二個a開頭,那麽形成的序列必然和先前的重復。
這種情況可以翻譯成:str[j] == s[i] && vis[j] == 1 (存在 j > i),故填入代碼str[i] == str[j] && vis[j]
2018 藍橋杯省賽 B 組模擬賽