[code] PTA 胡凡算法笔记 DAY042

题目 B1008 数组元素循环右移问题

在这里插入图片描述

  • 题意
    输入n个数即需要循环右移的次数m,采用最少的移动次数,输出最后移动后的结果。

  • 思路
    因为循环右移后只要移动一位(排除不需要移动的情况外)所有数都不在自己原来的位置上了,所以最少的次数至少是移动n次。这里采用的方式就是从需要开始移动的位置开始,把数放在临时变量中,不断用移动后的数字填充。有可能只需要遍历一趟就可以覆盖n个数,所以这里需要控制遍历的次数,根据最大公约数的含义可以得出其就是需要遍历的次数。可以举几个例子算算走走流程。

Q:最大公约数具有几何意义吗?
An:假设有一个长方体,其棱长分别为a、b、c,而a、b、c的最大公约数是p,那么,就可以把这个长方体切割成若干个棱长是p的正方体。这样分割出来的正方体个数是最少的。

  • Code in C++
#include <cstdio>
const int MAXN = 101;
int A[MAXN];
int gcd(int a, int b)
{
    if (b == 0) return a;
    else return gcd(b, a % b);
}

int main()
{
    int n, m, tmp, pos, next;
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; ++i)
    {
        scanf("%d", &A[i]);
    }

    m = m % n;
    if (m != 0)
    {
        int d = gcd(n, m); // d为n和m的最大公约数及覆盖整个数组需要遍历的次数
        for (int i = n - m; i < n - m + d; ++i)
        {
            tmp = A[i];
            pos = i;
            do {
                next = (pos - m + n) % n;
                if (next != i) A[pos] = A[next];
                else A[pos] = tmp;
                pos = next;
            } while (pos != i);
        }
    }

    printf("%d", A[0]);
    for (int i = 1; i < n; ++i)
    {
        printf(" %d", A[i]);
    }
}


小结

求最大公约数的方法:

  • 辗转相除法
  • 更相减损法
  • 质因数分解法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值