题意:给你一个公式:
X1 = 1
X2 = 2
X3 = 3
Xi = (Xi-1 + Xi-2 + Xi-3) % M + 1 for i = 4 to N
最多N个数,这些数组成一个序列,让你求出一个连续的序列1-K,在组成的1-K这个序列中,数的个数尽可能的少。
思路:一边填数据,一边筛选数据。找到一个最符合条件的数,进行两次扫描。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string.h>
#define maxn 1000101
using namespace std;
int T,N,M,K;
int num[maxn];
int c[maxn];
int min(int a,int b)
{
return a>b?b:a;
}
int main()
{
int ans;
int sum;
scanf("%d",&T);
for(int j=1; j<=T; j++)
{
memset(num,0,sizeof(num));
memset(c,0,sizeof(c));
ans=maxn;
scanf("%d%d%d",&N,&M,&K);
c[1]=1;
c[2]=2;
c[3]=3;
num[1]=num[2]=num[3]=1;
int l=1,r;
if(K<=3)
{
printf("Case %d: %d\n",j,K);
continue;
}
sum=3;
for(r=4; r<=N; r++)
{
c[r]=(c[r-1]+c[r-2]+c[r-3])%M+1;
if(!num[c[r]])
{
num[c[r]]=1;
if(c[r]>=1&&c[r]<=K)
{
// printf("c[r]=%d\n",c[r]);
sum++;
}
}
else
{
num[c[r]]++;
}
if(sum==K)
{
// printf("r=%d\n",r);
// printf("l=%d\n",l);
ans=min(ans,r-l+1);
}
while(l<=r)
{
if(c[l]>=1&&c[l]<=K&&num[c[l]]==1)
{
break;
}
num[c[l]]--;
l++;
if(sum==K)
{
ans=min(ans,r-l+1);
}
}
}
if(ans==maxn)
printf("Case %d: sequence nai\n",j);
else
printf("Case %d: %d\n",j,ans);
}
return 0;
}