zoukankan      html  css  js  c++  java
  • UVa 12174 Shuffle(滑动窗口)

    题意:

    你在听音乐播放器,它采用随机播放形式。随机播放的原理时先随机产生一个1~n的排列,然后就按这个排列顺序播放歌曲。播放完这序列的所有歌曲以后,再次随机生成一个1~n的排列,再继续播放。

    现在给你一个播放历史记录,这个历史记录是不完整的,以为它是开始记录时,已经有些歌曲播放过了而没有记录到。

    现在给你一段从某个时刻开始的播放音乐的历史记录,以及播放器里一共有多少首歌。

    问历史记录中第一首歌可能是某个随机列表中的第几首,总共有多少种可能?

    思路:

    滑动窗口,依次遍历,检查每个数能否作为循环的开始。

     1 #include<iostream> 
     2 #include<cstring>
     3 #include<set>
     4 using namespace std;
     5 
     6 const int N = 1e5 + 5;
     7 
     8 int s, n, a[N], vis[N];
     9 bool flag[N];
    10 int ans;
    11 
    12 void init() {
    13     cin >> s >> n;
    14     int num = 0;
    15     for (int i = 0; i < n; i++) {
    16         cin >> a[i];
    17         if (i < s) {   //对前面的s个进行分析
    18             if (vis[a[i]]) num++;   //统计前s个中重复的数字
    19             vis[a[i]]++;
    20         }
    21     }
    22 
    23     for (int i = 0; i < n; i++) {
    24         //如果num=0,说明前s个中没有重复的数字,那么第一个数字可以作为循环的开始
    25         if (num == 0) flag[i] = true;
    26 
    27         //窗口开始滑动
    28         if (vis[a[i]] == 2) num--;    //如果此时最左边的数为重复了的数,num需要减1
    29         vis[a[i]]--;
    30 
    31         int k = i + s;     //新数字进入滑动窗口
    32         if (k >= n) continue;
    33         if (vis[a[k]]) num++;   //如果已经出现过
    34         vis[a[k]]++;
    35     }
    36 }
    37 
    38 bool judge(int x) {   
    39     for (int i = x; i < n; i += s)
    40         if (!flag[i]) return false;
    41     return true;
    42 }
    43 
    44 void solve() {
    45     memset(vis, 0, sizeof(vis));
    46 
    47     ans = 0;
    48     for (int i = 0; i < s; i++) {
    49         if (judge(i)) ans++;
    50         if (i >= n) continue;
    51         //从左往右依次遍历,如果当前a[i]前面已经出现过,那么前面必须会有开头,此时必须结束循环
    52         if (vis[a[i]]) break;
    53         vis[a[i]]++;
    54     }
    55 }
    56 
    57 int main() {
    58     //freopen("D:\txt.txt", "r", stdin);
    59     int t;
    60     cin >> t;
    61     while (t--) {
    62         memset(flag, 0, sizeof(flag));
    63         memset(vis, 0, sizeof(vis));
    64         init();
    65         solve();
    66         cout << ans << endl;
    67     }
    68     return 0;
    69 }

    本来我是这样写的,结果不行,超时了。

     1 #include<iostream> 
     2 #include<cstring>
     3 #include<set>
     4 using namespace std;
     5 
     6 const int maxn = 100000 + 5;
     7 int a[maxn];
     8 int vis[maxn],flag[maxn];
     9 
    10 int s, n, ans;
    11 
    12 bool judge(int x)
    13 {
    14     for (int i = x; i < n; i += s)
    15     if (!flag[i]) return false;
    16     return true;
    17 }
    18 
    19 int main() {
    20     //freopen("D:\txt.txt", "r", stdin);
    21     int t;
    22     cin >> t;
    23     while (t--) 
    24     {
    25         memset(flag, 0, sizeof(flag));
    26         cin >> s >> n;
    27         for (int i = 0; i < n; i++)
    28         {
    29             cin >> a[i];
    30         }
    31         for (int i = 0; i < n; i++)
    32         {
    33             int ok = 0;
    34             memset(vis, 0, sizeof(vis));
    35             for (int j = i; j < i + s && j < n; j++)
    36             { 
    37                 if (vis[a[j]])    break;
    38                 vis[a[j]] = 1;
    39                 if (j == i + s - 1 || j==n-1)    ok = 1;
    40             }
    41             if (ok)     flag[i] = 1;
    42         }
    43         ans = 0;
    44         memset(vis, 0, sizeof(vis));
    45         for (int i = 0; i < s; i++)
    46         {
    47             if (judge(i))    ans++;
    48             if (i >= n)    continue;
    49             if (vis[a[i]])    break;
    50             vis[a[i]] = 1;
    51         }
    52         cout << ans << endl;
    53     }
    54     return 0;
    55 }
  • 相关阅读:
    Uva 10779 collector's problem
    poj 2728 最优比率树(最小生成树问题)
    LA 3126 二分图匹配 最小路径覆盖
    poj 1149 最大流构图
    Step By Step(Java XML篇)
    Step By Step(Java 输入输出篇)
    Step By Step(Java 集合篇)
    Step By Step(Java 线程篇)
    Step By Step(Java 反射篇)
    Step By Step(Java 国际化篇)
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6357707.html
Copyright © 2011-2022 走看看