1. 程式人生 > >2018 藍橋杯省賽 B 組模擬賽

2018 藍橋杯省賽 B 組模擬賽

最長 題意 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 組模擬賽