题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=4350
12年多校,1001题。
洗牌,n给的很大。
所以只要寻找到循环节,将n 模掉,再去暴力,剩余的时间复杂度就很低了~~~
貌似他们找的循环节都是 (r-l+1) 与 r 的最小公倍数。。。 但我找的是 它们之间的最大公约数 gcd,然后循环节就是 r / gcd 。。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int main(){
int t,tt;
int s[53],tmp[53];
int n,l,r;
scanf("%d",&t);
for(tt=1;tt<=t;tt++){
for(int i=1;i<=52;i++)
scanf("%d",&s[i]);
scanf("%d%d%d",&n,&l,&r);
int g=gcd(r,r-l+1);
n%=(r/g);
while(n--){
for(int i=0;i<=r-l;i++) tmp[i]=s[l+i];
for(int i=1;i<l;i++) tmp[r-l+i]=s[i];
for(int i=r+1;i<=52;i++) tmp[i-1]=s[i];
for(int i=0;i<52;i++) s[i+1]=tmp[i];
}
printf("Case #%d:",tt);
for(int i=1;i<=52;i++) printf(" %d",s[i]);
puts("");
}
return 0;
}