题意:

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

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

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

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

思路:

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

  1. #include<iostream>
  2. #include<cstring>
  3. #include<set>
  4. using namespace std;
  5.  
  6. const int N = 1e5 + ;
  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 = ;
  15. for (int i = ; 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 = ; i < n; i++) {
  24. //如果num=0,说明前s个中没有重复的数字,那么第一个数字可以作为循环的开始
  25. if (num == ) flag[i] = true;
  26.  
  27. //窗口开始滑动
  28. if (vis[a[i]] == ) 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, , sizeof(vis));
  46.  
  47. ans = ;
  48. for (int i = ; 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, , sizeof(flag));
  63. memset(vis, , sizeof(vis));
  64. init();
  65. solve();
  66. cout << ans << endl;
  67. }
  68. return ;
  69. }

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

  1. #include<iostream>
  2. #include<cstring>
  3. #include<set>
  4. using namespace std;
  5.  
  6. const int maxn = + ;
  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, , sizeof(flag));
  26. cin >> s >> n;
  27. for (int i = ; i < n; i++)
  28. {
  29. cin >> a[i];
  30. }
  31. for (int i = ; i < n; i++)
  32. {
  33. int ok = ;
  34. memset(vis, , sizeof(vis));
  35. for (int j = i; j < i + s && j < n; j++)
  36. {
  37. if (vis[a[j]]) break;
  38. vis[a[j]] = ;
  39. if (j == i + s - || j==n-) ok = ;
  40. }
  41. if (ok) flag[i] = ;
  42. }
  43. ans = ;
  44. memset(vis, , sizeof(vis));
  45. for (int i = ; i < s; i++)
  46. {
  47. if (judge(i)) ans++;
  48. if (i >= n) continue;
  49. if (vis[a[i]]) break;
  50. vis[a[i]] = ;
  51. }
  52. cout << ans << endl;
  53. }
  54. return ;
  55. }

UVa 12174 Shuffle(滑动窗口)的更多相关文章

  1. 紫书 例题8-15 UVa 12174 (滑动窗口)

    这道题就是给你一n长序列, 然后把这个序列按顺序分成很多段, 每段长s(最前面可以小于s, 只有第一段的后半段, 最后面也同样, 只有最后一段的前半段), 然后要求是每一段里面没有重复的数, 问你有几 ...

  2. UVa 12174 Shuffle (滑动窗口)

    题意:你正在使用的音乐播放器有一个所谓的乱序播放功能,即随机打乱歌曲的播放顺序.假设一共有s首歌, 则一开始会给这s首歌随机排序,全部播放完毕后再重新随机排序.继续播放,依次类推.注意,当s首歌播放完 ...

  3. Uva - 12174 - Shuffle

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

  4. 紫书 例题8-7 UVa 11572(滑动窗口)

    滑动窗口这个方法名字非常形象, 先是窗口的右指针尽量往右滑, 滑不动了就滑窗口的左指针, 滑到右指针又可以开始滑动为止. 这道题是要记录滑的过程中最大的窗口长度, 限制条件是窗口中不能出现重复的值. ...

  5. 紫书 习题 8-17 UVa 11536 (滑动窗口)

    这道题说连续子序列, 马上就想到滑动窗口. 注意窗口里面的元素中小于等于k的才是有效元素.记录窗口里面有效元素的个数, 满足了之后开始 缩短窗口, 如果左端点不是有效元素或者即使窗口中存在这个元素的个 ...

  6. UVA - 12174 Shuffle (预处理+滑动窗口)

    题意:已知歌单中的歌曲数目s,和部分的播放历史,问下一首可能播放的歌曲种数. 分析: 1.按照歌单数目s,将播放历史划分为几部分. 2.将播放历史的n首歌曲之前加上s首歌曲,之后加上s首歌曲,为防止标 ...

  7. 【uva 12174】Shuffle(算法效率--滑动窗口)

    题意:假设一种音乐播放器有一个乱序的功能,设定每播放S首歌为一个周期,随机播放编号为1~S的歌曲.现在给一个长度为N的部分播放记录,请统计下次随机排序所发生的时间的可能性种数.(1≤S,N≤10000 ...

  8. 12174 - Shuffle——[滑动窗口]

    You are listening to your music collection using the shuffle function to keep the music surprising. ...

  9. uva 1606 amphiphilic carbon molecules【把缩写写出来,有惊喜】(滑动窗口)——yhx

    Shanghai Hypercomputers, the world's largest computer chip manufacturer, has invented a new classof ...

随机推荐

  1. 【剑指offer】旋转数组的最小数字

    一.题目: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个 ...

  2. HTTP头部信息解释分析(详细整理)

    这篇文章为大家介绍了HTTP头部信息,中英文对比分析,还是比较全面的,若大家在使用过程中遇到不了解的,可以适当参考下 HTTP 头部解释 1. Accept:告诉WEB服务器自己接受什么介质类型,*/ ...

  3. vue学习七之Axios

    JQuery时代,我们使用ajax向后台提交数据请求,Vue时代,Axios提供了前端对后台数据请求的各种方式. 什么是Axios Axios是基于Promise的Http客户端,可以在浏览器和nod ...

  4. [javascript]编码&i字符串格式化&nput历史记录&清空模态框

    js中编码问题 https://www.haorooms.com/post/js_escape_encodeURIComponent 我在前端js添加时候创建dom时候,有汉字,发现是乱码就研究了下 ...

  5. POJ3009:Curling 2.0(dfs)

    http://poj.org/problem?id=3009 Description On Planet MM-21, after their Olympic games this year, cur ...

  6. SDUTOJ2465:其实玩游戏也得学程序(bfs+优先队列+回溯)

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2465 题目描述 由于前两次的打击,ZYJ同学不 ...

  7. POJ2983 Is the Information Reliable?

    http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=267#problem/B                        B -  ...

  8. selenium-python:登录网站并签到

    测试网站的图像验证码统一设置成了:121 Elements中定位元素比较费眼睛~~ import time from selenium import webdriver # import os use ...

  9. iOS UI基础-4.0应用程序管理

    功能与界面 功能分析: 以九宫格的形式展示应用信息 点击下载按钮后,做出相应的操作 步骤分析: 加载应用信息 根据应用的个数创建对应的view 监听下载按钮点击 整个应用界面: 程序实现 思路 UI布 ...

  10. 翻译[RFC6238] TOTP: Time-Based One-Time Password Algorithm

    在闲暇时间做了一个TOTP相关的开源项目,在项目初步完成之余,我尝试对[RFC6238]文档进行了翻译,供大家参考与查阅,若有不妥之处,还望各位前辈海涵斧正. [RFC6238] : Time-Bas ...