PAT 乙级 1008

  1. 数组元素循环右移问题 (20)
    时间限制
    400 ms
    内存限制
    65536 kB
    代码长度限制
    8000 B
    判题程序
    Standard

一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0
A1……AN-1)变换为(AN-M …… AN-1 A0
A1……AN-M-1)(最后M个数循环移至最前面的M个位置)。如果需要考虑程序移动数据的次数尽量少,要如何设计移动的方法?

输入格式:每个输入包含一个测试用例,第1行输入N ( 1<=N<=100)、M(M>=0);第2行输入N个整数,之间用空格分隔。

输出格式:在一行中输出循环右移M位以后的整数序列,之间用空格分隔,序列结尾不能有多余空格。 输入样例:

6 2 1 2 3 4 5 6

输出样例:

5 6 1 2 3 4

这一题我是6月份写了一次,2、3样例未通过,然后就忘记了他,今天又看见就做了一遍。

思路简单,就是改变数组内元素的位置,但是不能使用第二个数组就增加了难度,(虽然判分程序检测不出来)。其实题目的难点在于它并没有说明N>M,在测试的样例中,2、3样例就是N>M,所以我之前的代码就没有通过。在写程序的时候要注意把M换成M%N来处理这种情况。

如果只使用一个数组,那么就是数组内部交换顺序来达到输出效果。

其实这个题目可以投机取巧,在输出上下功夫,比如这样:

#include <stdio.h> 

int main(){
    int a, b, c[100], i;
    scanf("%d%d",&a,&b);

    for(i = 0; i < a; i++){
        scanf("%d",&c[i]);
    }
    for(i = a-b%a; i < a; i++)
        printf("%d ",c[i]);

    for(i = 0; i < a-b%a; i++){
        printf("%d",c[i]);
        if(i < a-b%a-1)printf(" ");
        }
    return 0;
}

也可以输入时候改变位置,通过代码如下:

#include <stdio.h>

int main()
{
    int n, m, c[100] = {0};

    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++)
        scanf("%d", &c[(i+m)%n]); 

    for (int i = 0; i < n; i++) {
        if (i > 0) printf(" ");
        printf("%d", c[i]);
    }
    return 0;
}

最开始写是利用数据结构的链表写的(因为当时正在学),现在看起来代码很繁琐。虽然后来通过了,BUT!!我使用了两个数组,不过还是附上源码,也算是数据结构的练习

#include <stdio.h>
#include <stdlib.h>
#define MaxSize 100

typedef struct{
  int elem[MaxSize];
  int last;
}list;

void InitList(list *L){  //初始化
  int i;
  for(i = 0; i < L->last; i++)
  L->elem[i] = -1;
}

void GetData(list *L){     //输入数据
  for(int i = 0; i < L->last; i++){
    scanf("%d",&L->elem[i]);
}
}

void Move(list *L,int a){      //移动数据
  int i, temp[MaxSize],j;      //temp数组用来存储移出的数字
  for(i = 0; i < L->last; i++)temp[i] = 0;
  for(i = 0; i < a%L->last; i++){
    temp[i] = L->elem[L->last - i - 1];
  }
  for(i = 0; i < L->last-a%L->last; i++){
    L->elem[L->last - i - 1] = L->elem[L->last - a%L->last - i - 1];
  }

  for(j = 0; j < a%L->last; j++){
    L->elem[a%L->last - 1 - j] = temp[j];
  }
}
void Print(list *L){
  for(int i = 0; i < L->last; i++){
  printf("%d",L->elem[i]);
  if(i < L->last - 1)printf(" ");
  }
}
int main(){
  int a;
  list L;
  scanf("%d%d",&L.last,&a);
  InitList(&L);
  GetData(&L);
  Move(&L,a);
  Print(&L);

  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值