UVA - 11536 - Smallest Sub-Array(滑动窗口)
题意:从给定字符串中,选最短连续子序列,包含1~k中的所有数。
尺取法(滑动窗口)解决:在第一次找到1~k的序列之后,向右滑动保证每个数至少存在一次,不断取最小值即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<cctype> 4 #include<cstdlib> 5 #include<cmath> 6 #include<iostream> 7 #include<sstream> 8 #include<iterator> 9 #include<algorithm> 10 #include<string> 11 #include<vector> 12 #include<set> 13 #include<map> 14 #include<deque> 15 #include<queue> 16 #include<stack> 17 #include<list> 18 typedef long long ll; 19 typedef unsigned long long llu; 20 const int MAXN = 100 + 10; 21 const int MAXT = 1000000 + 10; 22 const int INF = 0x7f7f7f7f; 23 const double pi = acos(-1.0); 24 const double EPS = 1e-6; 25 using namespace std; 26 27 int n, m, k, a[MAXT], T, vis[MAXN]; 28 29 void init(){ 30 a[0] = 1, a[1] = 2, a[2] = 3; 31 for(int i = 3; i < n; ++i) a[i] = (a[i - 1] + a[i - 2] + a[i - 3]) % m + 1; 32 } 33 34 int solve(){ 35 int head = 0, num = 0, ans = INF; 36 memset(vis, 0, sizeof vis); 37 for(int tail = 0; tail < n; ++tail) 38 if(a[tail] >= 1 && a[tail] <= k){ 39 if(!vis[a[tail]]) ++num; 40 ++vis[a[tail]]; 41 if(num == k){ 42 while((a[head] >= 1 && a[head] <= k && vis[a[head]] > 1) || a[head] < 1 || a[head] > k){ 43 if(a[head] >= 1 && a[head] <= k && vis[a[head]] > 1) --vis[a[head]]; 44 ++head; 45 } 46 ans = min(tail - head + 1, ans); 47 } 48 } 49 return ans == INF ? -1 : ans; 50 } 51 52 int main(){ 53 int ca = 0; 54 scanf("%d", &T); 55 while(T--){ 56 scanf("%d%d%d", &n, &m, &k); 57 init(); 58 int ans = solve(); 59 if(ans != -1) printf("Case %d: %d\n", ++ca, ans); 60 else printf("Case %d: sequence nai\n", ++ca); 61 } 62 return 0; 63 }

浙公网安备 33010602011771号