UVA12174-Shuffle(滑动窗口)
Posted npugen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA12174-Shuffle(滑动窗口)相关的知识,希望对你有一定的参考价值。
Accept: 240 Submit: 1743
Time Limit: 3000 mSec
Problem Description
You are listening to your music collection using the shu?e function to keep the music surprising. You assume that the shu?e algorithm of your music player makes a random permutation of the songs in the playlist and plays the songs in that order until all songs have been played. Then it reshu?es and starts playing the list again. You have a history of the songs that have been played. However, your record of the history of played songs is not complete, as you started recording songs at a certain point in time and a number of songs might already have been played. From this history, you want to know at how many di?erent points in the future the next reshu?e might occur. A potential future reshu?e position is valid if it divides the recorded history into intervals of length s (the number of songs in the playlist) with the ?rst and last interval possibly containing less than s songs and no interval contains a speci?c song more than once.
Input
On the ?rst line there exists one positive number: the number of test cases, at most 100. After that per test case there exists:
? One line with two integers s and n (1 ≤ s,n ≤ 100000): the number of di?erent songs in the playlist and the number of songs in the recorded playlist history.
? One line with n space separated integers, x1,x2,...,xn (1 ≤ xi ≤ s): the recorded playlist history.
Output
Sample Input
4 10
3 4 4 1 3 2 1 2 3 4
6 6
6 5 4 3 2 1
3 5
3 3 1 1 1
7 3
5 7 3
Sample Output
1
6
0
7
题解:有了滑动窗口的思路之后这个题就变得很简单了,一个可行解就是所有窗口都满足每个数至多出现一次,统计可行解的时候只需看前s个,因为一旦确定了第一个窗口的末尾,所有窗口就都确定了,而第一个窗口的末尾只可能出现在前s个。统计一个窗口是否满足条件时,维护一个数组和一个计数器,数组中存的是数字出现次数,计数器记录的是当前窗口中只出现一次的数有几个。如果窗口长度等于计数器的大小,该窗口就是满足条件的。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 100000 + 100; 6 7 int n, s; 8 int seq[maxn], vis[maxn]; 9 bool can[maxn]; 10 11 int main() 12 { 13 //freopen("input.txt", "r", stdin); 14 int iCase; 15 scanf("%d", &iCase); 16 while (iCase--) { 17 scanf("%d%d", &s, &n); 18 for (int i = 0; i < n; i++) { 19 scanf("%d", &seq[i]); 20 } 21 memset(vis, 0, sizeof(vis)); 22 memset(can, true, sizeof(can)); 23 24 int tot = 0; 25 for (int i = 0; i < n + s; i++) { 26 if (i < n) { 27 if (++vis[seq[i]] == 1) tot++; 28 } 29 if (i >= s) { 30 if (--vis[seq[i - s]] == 0) tot--; 31 } 32 if (min(n - 1, i) - max(i - s + 1, 0) + 1 != tot) can[i%s] = false; 33 } 34 35 int ans = 0; 36 for (int i = 0; i < s; i++) { 37 if (can[i]) ans++; 38 } 39 printf("%d ", ans); 40 } 41 return 0; 42 }
以上是关于UVA12174-Shuffle(滑动窗口)的主要内容,如果未能解决你的问题,请参考以下文章
UVA - 12174 Shuffle (预处理+滑动窗口)
UVa11572 Unique Snowflakes (滑动窗口)