Uva - 12174 - Shuffle

来源:互联网 发布:软件平台验收报告 编辑:程序博客网 时间:2024/05/29 11:52



用滑动窗口的思想,用一个数组保存每个数在窗口中出现的次数。再用一个变量记录在窗口中恰好出现一次的的数的个数,这样可以枚举所有可能的答案,判断它所对应的所有串口,当且仅当所有的串口均满足要求时这个答案可行。
AC代码:

#include <iostream>#include <cstdio>#include <cstdlib>#include <cctype>#include <cstring>#include <string>#include <sstream>#include <vector>#include <set>#include <map>#include <algorithm>#include <stack>#include <queue>#include <bitset> #include <cassert> #include <cmath>#include <functional>using namespace std;const int maxn = 100005;int s, n, tot;int x[maxn * 3], cnt[maxn], ok[maxn * 2];void solve(){for (int i = 0; i < n + s + 1; i++) {if (tot == s) { // 完整的窗口ok[i] = 1;}if (i < s && tot == i) { // 刚开始左侧窗口不完整ok[i] = 1;}if (i > n && tot == n + s - i) { // 结束的时候右侧的窗口不完整ok[i] = 1;}// 为下一次滑动窗口更新cnt和totif (i == n + s) { // 滑到头了break;}if (x[i] != -1 && --cnt[x[i]] == 0) { // 删掉第一个tot--;}if (x[i + s] != -1 && cnt[x[i + s]]++ == 0) { // 增加一个tot++;}}}int main(){ios::sync_with_stdio(false);int T;cin >> T;while (T--) {cin >> s >> n;// 给每个数字左右都加一个-1fill(x, x + n + 2 * s, -1);for (int i = 0; i < n; i++) {cin >> x[i + s];}tot = 0; // 当前华东窗口有多少个不同的数字fill(cnt + 1, cnt + s + 1, 0);// cnt[i]是i在当前滑动窗口的数量fill(ok, ok + n + s + 1, 0);// 如果第i个滑动窗口没有一样的数字则ok[i] = 1solve();int ans = 0;// 检查每个可能的结果for (int i = 0; i < s; i++) {int valid = 1;// 所有窗口满足要求,这个结果才是可行的for (int j = i; j < n + s + 1; j += s) {if (!ok[j]) {valid = 0;}}if (valid) {ans++;}}if (ans == n + 1) {ans = s;}cout << ans << endl;}return 0;}


0 0
原创粉丝点击