西安邀请赛-L(打表找规律)

一时失言乱红尘 2021-12-21 01:05 383阅读 0赞

题目链接:https://nanti.jisuanke.com/t/39279

题意:给定n个不同的数表示的序列,定义两种操作:1. 交换前一半和后一半(如果有奇数个,则中间的不管)。2. 交换每个偶数位和它之前的数(如果有奇数个,最后一个不管)。问通过这两种操作,可以得到多少个不同的序列。

思路:典型的打表找规律的题,下次比赛吸取教训。打表的代码如下:

ContractedBlock.gif ExpandedBlockStart.gif

  1. #include<cstdio>
  2. using namespace std;
  3. int a[10005],b[10005];
  4. int n,ans;
  5. bool check(){
  6. bool flag=1;
  7. for(int i=1;i<=n;++i)
  8. if(a[i]!=b[i]){
  9. flag=0;
  10. break;
  11. }
  12. return flag;
  13. }
  14. int main(){
  15. for(n=1;n<=30;++n){
  16. int hf=n/2;
  17. ans=0;
  18. for(int i=1;i<=n;++i)
  19. a[i]=i,b[i]=i;
  20. while(1){
  21. for(int i=1;i<=hf;++i){
  22. int tmp=b[i];
  23. b[i]=b[n-hf+i];
  24. b[n-hf+i]=tmp;
  25. }
  26. if(check()) break;
  27. ++ans;
  28. for(int i=1;i<=n-1;i+=2){
  29. int tmp=b[i];
  30. b[i]=b[i+1];
  31. b[i+1]=tmp;
  32. }
  33. if(check()) break;
  34. ++ans;
  35. }
  36. printf("%d:%d\n",n,ans+1);
  37. }
  38. return 0;
  39. }

然后就可以找到规律了:

n%4==0: ans=4

n%4==1: if(n==1) ans=1

     else ans=2*n

n%4==2: ans=n

n%4==3: if(n==3) ans=6

     else ans =12

AC代码:

  1. #include<cstdio>
  2. using namespace std;
  3. int a[10005],b[10005];
  4. int n,ans;
  5. bool check(){
  6. bool flag=1;
  7. for(int i=1;i<=n;++i)
  8. if(a[i]!=b[i]){
  9. flag=0;
  10. break;
  11. }
  12. return flag;
  13. }
  14. int main(){
  15. for(n=1;n<=30;++n){
  16. int hf=n/2;
  17. ans=0;
  18. for(int i=1;i<=n;++i)
  19. a[i]=i,b[i]=i;
  20. while(1){
  21. for(int i=1;i<=hf;++i){
  22. int tmp=b[i];
  23. b[i]=b[n-hf+i];
  24. b[n-hf+i]=tmp;
  25. }
  26. if(check()) break;
  27. ++ans;
  28. for(int i=1;i<=n-1;i+=2){
  29. int tmp=b[i];
  30. b[i]=b[i+1];
  31. b[i+1]=tmp;
  32. }
  33. if(check()) break;
  34. ++ans;
  35. }
  36. printf("%d:%d\n",n,ans+1);
  37. }
  38. return 0;
  39. }

转载于:https://www.cnblogs.com/FrankChen831X/p/10927161.html

发表评论

表情:
评论列表 (有 0 条评论,383人围观)

还没有评论,来说两句吧...

相关阅读