zoukankan      html  css  js  c++  java
  • Day4 T1 数列变换

    题目

      小X看到堆成山的数列作业十分头疼,希望聪明的你来帮帮他。考虑数列(A=)[(A_1)(A_2)……(A_n)],定义变换f(A,k)=[(A_2)(A_3)……(A_k)(A_1)(A_{k+2})(A_{k+3})……(A_{2k})(A_{k+1})……],也就是把A分段,每段k个(最后如果不足k个,全部分到新的一段里,详见样例),然后将每段的第一个移动到该段的最后一个。
      现在,小X想知道 f(f(f(f([1,2,3,⋯,n],2),3),⋯),n)的结果。

    输入

    输入一行包含一个整数n。

    输出

    输出一行包含n 个整数,表示最终的数列。

    样例

    输入 输出
    4 4 2 3 1

    数据范围

    对于60%的数据,1≤n≤(10^3)
    对于100%的数据,1≤n≤(10^6)

    题解

      仔细观察可以发现,每次前一段的第一个数移动到了后一段的第一个。
      每次将前一段的第一个数移动到后一段的第一个的位置,那么每次将前一段的第一个数移动到后一段的第一个,最终整个数列总的就移动了n-1次。只需开一个两倍大的数组,再记录当前数列的头部位置即可。
    (我这里用了滚动数组,看了一位Dalao的代码,发现只需用swap即可STL大法好

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,head,inv=0;
    int a[2000010]={0},t[2]={0};
    
    void init(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++) a[i]=i;
        head=1;
    }
    
    void work(int k){
        for(int i=head;i<=n+head-1;i+=k){
            t[inv]=a[i];
            a[i]=t[inv^1];
            inv^=1;
            if(i+k>n+head-1) a[n+head]=t[inv^1];
        }
    }
    
    int main(){
    	init();
        for(int i=2;i<=n;i++){
            work(i);
            head++;
        }
        for(int i=head;i<n+head-1;i++) printf("%d ",a[i]);
        printf("%d",a[n+head-1]);
    	return 0;
    }
    
  • 相关阅读:
    B. Pasha and Phone
    GCD(关于容斥原理)
    二分乘法
    Lucky7(容斥原理)
    E. Devu and Flowers
    最大公约数最小公倍数
    leetcode每日刷题计划--day55
    Titanic--kaggle竞赛入门-生存预测
    做题记录--day54
    机器学习上机作业1记录 && 相关知识点复习
  • 原文地址:https://www.cnblogs.com/znk161223/p/11516643.html
Copyright © 2011-2022 走看看