You are listening to your music collection using the shuffle function to keep the music surprising. You
assume that the shuffle 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 reshuffles 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 different points in
the future the next reshuffle might occur.
  A potential future reshuffle 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 specic song more than once.
Input
On the rst line one positive number: the number of testcases, at most 100. After that per testcase:
• One line with two integers s and n (1 ≤ s, n ≤ 100000): the number of different 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
Per testcase:
• One line with the number of future positions the next reshuffle can be at. If the history could
not be generated by the above mentioned algorithm, output 0.
Sample Input
4
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

题意理解:

  给定长度为n的播放历史记录,推断下一次重排的时间点的可能情况数目。注意首尾两段的记录允许不完整(小于s)。

  特殊情况:当n<s时,如果记录中的每首歌均无重复,比如:

  7 3

  5 7 3

  5号歌之前可能还存在1~7(大于7时的情况是等效的)首歌已经播放却没有加入记录,那么下一次重排点就有这7种情况。

解题思路:

  使用滑动窗口的思想进行预处理:对n中的第i个数,如果紧随其后的s个数均没有重复,那么以i为起始的窗口是合法的。 

  

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <set>
#define time_ printf("time = %f\n",double(clock())/CLOCKS_PER_SEC)
using namespace std;
const int maxn=;
int s,n;
int seq[maxn+];
int num[maxn+];
int id[maxn+]; void pre_process(){
int l=,r=;
memset(num,,sizeof num);
memset(id,,sizeof id);
int single=;
for(;r<l+s&&r<n;r++){
int id=seq[r];
num[id]++;
if(num[id]==) single++;
else single--;
}
if(single==r-l) id[l]=;
while(l<n){
int a=seq[l];
int b=seq[r];
num[a]--;
if(num[a]==) single--;
if(num[a]==) single++;
l++;
if(r!=n){
num[b]++;
if(num[b]==) single++;
if(num[b]==) single--;
r++;
}
if(l!=n&&single==r-l) id[l]=;
}
}
int main(int argc, const char * argv[]) {
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&s,&n);
for(int i=;i<n;i++)
scanf("%d",&seq[i]);
pre_process();
int ans=;
int rst[maxn+];
memset(rst,,sizeof rst);
rst[seq[]]++;
int single=;
for(int d=;d<=s&&d<=n;d++){
bool ok=true;
if(single!=d) break;;
for(int pt=d;pt<n;pt+=s){
if(id[pt]==){
ok=false;
break;
}
}
if(ok) ans++;
rst[seq[d]]++;
if(rst[seq[d]]==) single++;
}
if(n<s&&ans==n)
ans=s;
printf("%d\n",ans);
}
return ;
}

最新文章

  1. iOS关于通知传值Bool类型的注意点
  2. hibernate.hbm2ddl.auto配置详解
  3. SortedSet接口
  4. Effective C++ -----条款23:宁以non-member、non-friend替换member函数
  5. 【转】cas注册后自动登录
  6. Python学习总结8:文件模式及操作方法汇总
  7. POJ 3468 线段树裸题
  8. shell shift 使用一例
  9. Java基础中的一些注意点
  10. C++链表与键值对
  11. Netty 5.0源码分析之综述
  12. Apache的作用及意义
  13. Java内存溢出分析方法(Eclipse Memory Analyzer 使用简单入门)
  14. 笔记|《简明Python教程》:编程小白的第一本python入门书
  15. HTML5经常使用知识
  16. [HNOI 2015]亚瑟王
  17. go语言开发教程之web项目开发实战
  18. leecode第三百四十四题(反转字符串)
  19. Django2.0跨域请求配置
  20. windows下搭建voip服务器

热门文章

  1. Leetcode884.Uncommon Words from Two Sentences两句话中的不常见单词
  2. ThInkPHP验证码不显示,解决方法汇总
  3. python 字符串匹配算法设计
  4. 阿里云MaxCompute 2019-6月刊
  5. 网络流24题 最小路径覆盖(DCOJ8002)
  6. Linux下配置 Keepalived(心跳检测部署)
  7. laravel 参数设置
  8. 【JZOJ4868】【NOIP2016提高A组集训第9场11.7】Simple
  9. xib搭建scrollView无法滑动的问题
  10. 2018-10-19-Roslyn-使用-Directory.Build.props-文件定义编译