原题: https://www.patest.cn/contests/pat-b-practise/1008

题意理解: 假设n=6, 需要移位的序列是: 1 2 3 4 5 6, 如果m=2, 从6开始看, 把6
移动2个位置, 6就到了2的位置, 同样把5移动2个位置, 5就到了1的位置, 依次类推.
下面考虑一些特殊情况:
m=0, 很显然原序列不进行任何移动
m=6, 把6移动6个位置, 结果仍然是原序列
m=7, 现在m>n, 根据题意这种情况是可能的, 把6往右移动7个位置, 我们发现6移到了1的位置.
总结以上分析, 可以得出, 移动的次数m = m % n

解题思路: 本题有多种解法, 但不少方法感觉不太道义或不太合理.
第1种, 不管题目要求, 直接使用2个数组.
第2种, 利用C语言特性, 通过循环一个一个读取数据, 读取一个数据就通过计算把这个数据放在合适
的位置, 利用这种方法, 简直可以实现数据"0"移动
第3种, 不进行数据移动, 而是控制打印顺序. 这个很好理解, 比如6个数, [1 2 3 4 5 6], m=2,
也就是全体往右移动2个位置, 我们可以先打印5 6, 再打印1 2 3 4
第4种, 使用链表实现, 这个方法感觉比较合理(下有详细解释)
第5种, 使用数组模拟链表实现, 用链表实现代码量可能很长, 用数组模拟链表很简单, 声明一个空间
较大的数组, 然后从数组的中间开始存数据, 这样涉及到移动数据时, 只需把后面的数据插在前面即可.
这种方法缺点很明显, 就是占用空间可能比较大, 但就解本题来说, 是完全可以的.
第6种, 如果必须限定只能使用数组, 数组大小只能等于n. 可以利用移位算法来实现, 这种方法比较难
理解, 我在网上看到有大牛实现了, 可以参考这里:
http://blog.csdn.net/xtzmm1215/article/details/38407799

第3种实现方法, 控制打印顺序, 完整实现代码:

#include <stdio.h>int main () {int i;int n;int m;char ch = ' '; // 打印控制变量, 默认空格int arr[100];  // 下标0, 不存数据scanf("%d", &n);scanf("%d", &m);m = m % n; // 确保 m < n// 给数组赋值for (i=1; i<=n; i++) {scanf("%d", &arr[i]);}// 接下来分两次, 分别控制打印顺序// 第1次打印, 从倒数第m个数开始for (i=n-m+1; i<=n; i++) {printf("%d ", arr[i]);}// // 第2次打印, 从1到倒数第m个数for (i=1; i<=n-m; i++) {if (i == (n - m)) {ch = '\n';}printf("%d%c", arr[i], ch);}return 0;
}

链表实现

使用链表实现, 根据题意至少需要实现链表的插入, 删除, 定位操作.
一般情况下, 大部分操作都是把链表后面的元素拿到前面, 如果真的追求最少的移动次数,
可以添加判断条件, 从而有些情况需要把链表前面的元素移动到后面.
我们这里为了简单, 插入只有2种情况一种是在头部插入一种是在尾部插入.
由于我们结构体只有一个数据域data, 所以在执行删除(在题目里面相当于移动)操作时, 只要
事先保存着数据域的值, 就可以把该节点彻底从链表中移除(free)

完整实现代码:

#include <stdio.h>struct list {int data;struct list *next;
};
typedef struct list s_list;
typedef struct list *p_list;p_list insert (p_list p, int x);
void print (p_list head);
int del (p_list head, p_list *rear);int main () {int i;int n;        // 链表元素个数int m;        // 右移位数int x;        // 当前读取的数p_list head;  // 头指针p_list rear;  // 尾指针head = (s_list*)malloc(sizeof(s_list));head->next = NULL;rear = head;scanf("%d", &n);scanf("%d", &m);m = m % n;// 为链表赋值for (i=1; i<=n; i++) {scanf("%d", &x);rear = insert(rear, x); // 动态修改尾指针的指向}// 对链表进行移动for (i=1; i<=m; i++) {x = del(head, &rear);insert(head, x);}print(head);return 0;
}// 在p元素的后面插入一个元素x
// 返回值: 返回一个指向被删元素的指针
p_list insert (p_list p, int x) {p_list temp = (s_list*)malloc(sizeof(s_list));temp->data = x;temp->next = p->next;p->next = temp;return temp;
}// 删除一个尾元素, 并返回其值
// 把链表元素的一个节点整个从程序中移除并无大碍, 只要被删元素
// 的值, 被保存下来, 以后随时可以重建被删节点
// 该函数需要在内部改变rear的指向, 因此需要定义指针的指针
int del (p_list head, p_list *rear) {p_list pre;      // 最后一个元素的前一个元素p_list tempRear; // 指向被删元素, 也就是最后一个元素int value;       // 被删除元素的值value = (*rear)->data; // 又是运算符优先级的坑tempRear = *rear;pre = head->next;while (pre->next != *rear) {pre = pre->next;}*rear = pre;(*rear)->next = NULL;free(tempRear);return value;
}// 打印链表
void print (p_list head) {p_list p;char ch = ' '; // 打印控制变量p = head->next;while (p != NULL) {if (p->next == NULL) {ch = '\n';}printf("%d%c", p->data, ch);p = p->next;}
}

转载于:https://www.cnblogs.com/asheng2016/p/7661311.html

1008. 数组元素循环右移问题 (20)相关推荐

  1. C++学习之路 | PTA乙级—— 1008 数组元素循环右移问题 (20分)(精简)

    1008 数组元素循环右移问题 (20分) 一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A ​0 ​​ A ​1 ​​ ...

  2. 浙江大学PAT上机题解析之1008. 数组元素循环右移问题 (20)

    1008. 数组元素循环右移问题 (20) 时间限制  400 ms 内存限制  32000 kB 代码长度限制  8000 B 判题程序    Standard 一个数组A中存有N(N>0)个 ...

  3. 1008. 数组元素循环右移问题 (20)-PAT乙级真题

    一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1--AN-1)变换为(AN-M -- AN-1 A0 ...

  4. Basic Level 1008. 数组元素循环右移问题 (20)

    一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1--AN-1)变换为(AN-M -- AN-1 A0 ...

  5. 极高效代码(C语言):1008 数组元素循环右移问题 (20分)

    立志用更少的代码做更高效的表达 Pat乙级最优化代码+题解+分析汇总-->传送门 一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将 ...

  6. 1008 数组元素循环右移问题 (20)

    一个数组A中存有N(N&gt0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A~0~ A~1~--A~N-1~)变换为(A~N-M~ ...

  7. PAT 乙级 1008. 数组元素循环右移问题 (20) Java版

    一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0A1--AN-1)变换为(AN-M -- AN-1 A0  ...

  8. 【PAT乙级】1008 数组元素循环右移问题 (20 分)

    https://pintia.cn/problem-sets/994805260223102976/problems/994805316250615808 方法一: 用一个数组保存移动动后的数组 #i ...

  9. 1008 数组元素循环右移问题 (20分)

    输入样例: 6 2 1 2 3 4 5 6 输出样例: 5 6 1 2 3 4 # -*- coding: utf-8 -*- import mathdef right_shift(lst, m):n ...

最新文章

  1. 【MATLAB】交互式绘图(ginput,gtext,zoom)
  2. 如何起一个好的学术期刊论文题目?
  3. java gpg_gpg的使用
  4. Python 赋值、浅拷贝、深拷贝的区别?
  5. 禁止和恢复WIN7驱动强制签名
  6. JavaScript - reduce用法详解
  7. Unity3D学习笔记之二资源导入以及工程管理
  8. android studio聊天跳转_Android 第三方应用跳转到QQ进行聊天
  9. 在索引列上正确使用LIKE运算符
  10. Activity生命周期详解一
  11. 序列标注模型结果评估模块seqeval学习使用
  12. echarts 地图散点
  13. java大鱼吃小鱼实验报告摘要_java 大鱼吃小鱼游戏总结
  14. MySql查询当前版本
  15. HTML5面试题及答案
  16. 【python-Unet】计算机视觉~舌象舌头图片分割~机器学习(三)
  17. 推荐:几个优质的数据公众号
  18. 21世纪东方美女标准[男士参考女士学习]
  19. [思维模式-9]:《如何系统思考》-5- 认识篇 - 改变开环、组合逻辑的线性思考,实施闭环、时序逻辑的动态思考。
  20. Silverlight的开发工具 1

热门文章

  1. 关于Puppet不得不说的故事
  2. Liux技巧总结之--解压各种文件
  3. 使用MrBayes构建贝叶斯系统发育树【实践】
  4. 基于百度地图的python开发服务端_python编程之API入门: (一)使用百度地图API查地理坐标...
  5. 17、计算机图形学——辐射度量学
  6. Python知识点5——字典
  7. push_back()和emplace_back()函数
  8. VISP视觉库识别AprilTag详细解读
  9. linux 程序输出 logo,Linux下制作logo并显示到开发板上
  10. 软件测试人员需要掌握的linux命令(一)