# 題目: UVa 11536 - Smallest Sub-Array
# 題目說明
建構出按照一定規則的數字序列
找出包含所有 1 - K
的最短子序列
序列的規則如下:
x1
= 1x2
= 2x3
= 3xi
= (xi-1 + xi-2 + xi-3) % M + 1
INPUT:
第一行有一個整數 T
,代表有幾筆資料
每筆資料有 3 個整數 N
、 M
、 K
N
代表數字序列的長度M
代表xi
取M
的餘數K
代表目標數字
OUTPUT:
輸出最短子序列的長度
如果不存在,則輸出 sequence nai
# 解題方法
按照 N
的大小先建構數字序列,以 G
儲存
從頭開始遍歷 G
,計算每個符合條件 (<=K) 的數字數量
如果為第 1 次新增,則將 cnt + 1
,當 cnt = K
,則找到一個符合條件的子序列
比對是否比其他序列更短,並盡可能的縮減序列 (從頭開始刪除)
# 參考程式碼
#include <iostream> | |
#include <vector> | |
#include <algorithm> | |
using namespace std; | |
int main() | |
{ | |
// fast io | |
ios::sync_with_stdio(false); | |
cin.tie(nullptr); | |
cout.tie(nullptr); | |
int T, N, M, K, cases = 0; | |
vector<int> G; | |
vector<int> check; | |
cin >> T; | |
while (T--) | |
{ | |
cin >> N >> M >> K; | |
// init | |
G.assign(N + 1, 0); | |
G[1] = 1, G[2] = 2, G[3] = 3; | |
for (int i = 4; i <= N; ++i) G[i] = (G[i - 1] + G[i - 2] + G[i - 3]) % M + 1; | |
check.assign(K + 1, 0); | |
// find the smallest subsequence | |
int result = N + 1; | |
for (int i = 1, f = 1, cnt = 0; i <= N; ++i) | |
{ | |
if (G[i] > K) continue; | |
else if (++check[G[i]] == 1) ++cnt; | |
while (f <= i && cnt == K) | |
{ | |
if (G[f++] > K) continue; | |
result = min(result, i - f + 2); | |
if (--check[G[f - 1]] == 0) --cnt; | |
} | |
} | |
cout << "Case " << ++cases << ": "; | |
if (result == N + 1) cout << "sequence nai\n"; | |
else cout << result << "\n"; | |
} | |
return 0; | |
} |
# 參考資料
https://blog.csdn.net/keshuai19940722/article/details/18883357