zoukankan      html  css  js  c++  java
  • 【uva 12174】Shuffle(算法效率--滑动窗口)

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

    解法由“连续的S个数”想到滑动窗口。O(n)循环一次,每次判断一个周期的[i-S+1,i]是否可行,记录入tf[i]。最后O(n)枚举第一个“窗口”的初始结束位置来得到可能性种数。

    实现:在N个数后另外添加S-1个与之前都互不相同的数,以补全最后几个数的周期。当然,像一开始的几个数一样特判也可以。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<iostream>
     6 using namespace std;
     7 const int N=100010,D=100010;
     8 
     9 int a[2*N],v[2*N];
    10 bool tf[2*N];
    11 
    12 int main()
    13 {
    14     int T,n,s;
    15     int i,j,k,tot;
    16     scanf("%d",&T);
    17     while (T--)
    18     {
    19       scanf("%d%d",&s,&n);
    20       memset(tf,0,sizeof(tf));
    21       memset(v,0,sizeof(v));
    22       for (i=1;i<=n;i++) scanf("%d",&a[i]);
    23       for (i=1;i<s;i++) a[n+i]=s+i;
    24       tot=0;
    25       for (i=1;i<n+s;i++)
    26       {
    27         if (v[a[i]])
    28         {
    29           k=v[a[i]];
    30           for (j=v[a[i]];j>=i-tot;j--)
    31             v[a[j]]=0;
    32           tot=i-k-1;
    33         }
    34         if (tot==s) v[a[i-tot]]=0,tot--;
    35         tot++,v[a[i]]=i;
    36         if (tot==s) tf[i]=true;
    37         if (i<s && tot==i) tf[i]=true;
    38       }
    39       tot=0;
    40       for (i=1;i<=s;i++)
    41       {
    42         bool ok=true;
    43         for (j=i;j<n+s;j+=s)
    44           if (!tf[j]) {ok=false;break;}
    45         if (ok) tot++;
    46       }
    47       printf("%d
    ",tot);
    48     }
    49     return 0;
    50 }
    View Code

    另外,我几天前按紫书说的“直接一点”的方法:据相同的数的相邻出现排除一些非法区间,利用这些并集得出答案。打了很久,调了很久,但一直WA~(搞得我这之后去做了几题图论了。qwq)求正解~

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<iostream>
     6 using namespace std;
     7 const int N=100010,D=100010;
     8 //Shuffle 2  WA
     9 int a[N],last[N],first[N];
    10 int mmin(int x,int y) {return x<y?x:y;}
    11 int mmax(int x,int y) {return x>y?x:y;}
    12 int main()
    13 {
    14     int T,n,s;
    15     scanf("%d",&T);
    16     while (T--)
    17     {
    18       scanf("%d%d",&s,&n);
    19       for (int i=1;i<=s;i++)
    20         last[i]=first[i]=-s;
    21       int l=s+1,r=0,x,ans=s;
    22       for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    23       for (int i=1;i<=n;i++)
    24       {
    25         if (first[a[i]] && i-first[a[i]]<s+1) {ans=0;break;}
    26         {
    27           int t=i-last[a[i]];
    28           if (t<=s)
    29           {
    30             int ll=(i+1)%s,rr=last[a[i]]%s;
    31             if (ll>rr) x=ll,ll=rr,rr=x;
    32             l=mmin(l,ll),r=mmax(r,rr);
    33           }
    34         }
    35         first[a[i]]=last[a[i]],
    36         last[a[i]]=i;
    37       }
    38       if (ans && l<=r) ans-=r-l+1;
    39       if (s==1) ans=1;
    40       printf("%d
    ",ans);
    41     }
    42     return 0;
    43 }
    WA
  • 相关阅读:
    测试一下你的T-SQL基础知识-count
    测试一下你的T-SQL基础知识-subquery
    Microsoft SQL Server 2012 管理 (2): Auditing
    Webpack
    react
    Webpack 傻瓜式指南(一)
    谈谈react-router学习
    使用Flexible 实现手淘H5 页面的终端适配学习
    Promise 让异步更优
    基于LeanCloud云引擎的Web全栈方案
  • 原文地址:https://www.cnblogs.com/konjak/p/6024311.html
Copyright © 2011-2022 走看看