例题8-15 Shuffle的播放记录(Shuffle, ACM/ICPC NWERC 2008, UVa 12174)

来源:互联网 发布:weka java api 编辑:程序博客网 时间:2024/05/21 03:27
思路:
枚举前s个数作为开头的情况。
首先,可以运用滑动窗口法来预处理出所有点起始长为s的排列是否存在,复杂度为O(n)。
接着,check的过程复杂度为s*n/s, 同样为O(n)。
#include <set>#include <map>#include <ctime>#include <cmath>#include <stack>#include <queue>#include <deque>#include <cstdio>#include <string>#include <vector>#include <cctype>#include <sstream>#include <utility>#include <cstring>#include <cstdlib>#include <functional>#include <iostream>#include <algorithm>#define SF(a) scanf("%d", &a)#define PF(a) printf("%d\n", a)  #define SFF(a, b) scanf("%d%d", &a, &b)  #define SFFF(a, b, c) scanf("%d%d%d", &a, &b, &c)#define SFFFF(a, b, c, d) scanf("%d%d%d%d", &a, &b, &c, &d)#define CLEAR(a, b) memset(a, b, sizeof(a))#define IN() freopen("in.txt", "r", stdin)#define OUT() freopen("out.txt", "w", stdout)#define FOR(i, a, b) for(int i = a; i < b; ++i)#define LL long long#define maxn 100005#define maxm 205#define mod 1000000007#define inf 1000000007#define eps 1e-4using namespace std;int buf[20], l;int read() {int x = 0; char ch = getchar(); bool f = 0;while (ch < '0' || ch > '9') { if (ch == '-') f = 1; ch = getchar(); }while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();return f ? -x : x;}void write(int x) {if (!x) { putchar(48); return; }l = 0; if (x < 0) putchar('-'), x = -x;while (x) buf[++l] = x % 10, x = x / 10;while (l) putchar(buf[l--] + 48);}//-------------------------chc------------------------------//int s, n, a[maxn], vis[maxn];bool ok[maxn];void pre() {CLEAR(ok, 0);CLEAR(vis, 0);for (int i = 0; i < n; ++i) a[i] = read();int cnt = 0;//记录重复元素的个数for (int i = 0; i < s && i < n; ++i) // 建立第一个滑动窗口, 注意s可能大于nif (vis[a[i]]++) cnt++;for (int front = 0; front < n; ++front) {if (cnt == 0) ok[front] = true;if (--vis[a[front]]) cnt--;int rear = front + s;if (rear < n)if (vis[a[rear]]++) cnt++;}}bool check(int pos) {for (int i = pos; i < n; i += s)if (!ok[i]) return false;return true;}void solve() {CLEAR(vis, 0);int ans = 0;for (int i = 0; i < s; ++i) {if (check(i)) ++ans;if (i >= n) continue;if (vis[a[i]]++) break;}PF(ans);}int main() {int t = read();while (t--) {s = read(), n = read();pre();solve();}return 0;}


原创粉丝点击