鱼C论坛

 找回密码
 立即注册
查看: 1504|回复: 10

[已解决]patbasic1008

[复制链接]
发表于 2022-3-4 16:24:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目:
Image 1.png Image 2.png
#include <stdio.h>
int main(void)
{
    int n,i,t;//n为 输入个数,t为移动距离
    int a[100];
    scanf("%d %d",&n,&t);

    t %= n;//防止t比n大
   for(i=0;i<n;i++)
    {
        scanf("&d",&a[i]);
    }
    for(i = (n - t);i < n;i++)
    {
        printf("%d",a[i]);
    }
    for(i = 0;i < (n - t) ;i++)
    {
        printf("%d",a[i]);
    }
}
请问这个程序有什么问题,谢谢大佬。
最佳答案
2022-3-4 22:51:48
本帖最后由 jackz007 于 2022-3-5 00:24 编辑
a327904410 发表于 2022-3-4 22:24
知道,就是中间的 for 循环 k 的值又恰好是最后排列的结果,感觉很神奇


       没有什么好神奇的,当 n = 6 的时候,a[] = {1 , 2 , 3 , 4 , 5 , 6},如果 m = 2,那么,经过移动以后的 a[] = {5 , 6 , 1 , 2 , 3 , 4},只要确定移动后的 a[0] = 5,那么,就按从小到大依序向 a[] 中填入 6 个数值,a[] = {5 , 6 , 7 , 8 , 9 , 10},但是,我们知道,a[] 中没有数值超过 6 的元素,所以,还需要为所有数值超过 6 的元素减掉 6 ,这样,我们就得到了 a[] = {5 , 6 , 1 , 2 , 3 , 4}。
       2 楼的代码已经重新优化,与本解题思路相一致。

       下面是递归函数版本的代码
#include <stdio.h>

void move(int d[] , int n , int m , int c)
{
        int i , k                                                                     ;
        if(n > m) {
                if(c < m) {
                        k = d[n - m + c]                                              ;
                        move(d , n , m , c + 1)                                       ;
                        d[c] = k                                                      ;
                } else {
                        for(i = 0 ; i < n - m ; i ++) d[n - 1 - i] = d[n - m - 1 - i] ;
                }
        }
}

int main(void)
{
        int a[100] , i , m , n                                                        ;
        scanf("%d%d" , & n , & m)                                                     ;
        if(n > m && m > 0) {
                for(i = 0 ; i < n ; i ++) a[i] = i + 1                                ;
                move(a , n , m , 0)                                                   ;
                for(i = 0 ; i < n ; i ++) {
                        if(i) printf(" ")                                             ;
                        printf("%d" , a[i])                                           ;
                }
        }
}
        编译、运行实况
D:\[00.Exerciese.2022]\C>g++ -o k k.c

D:\[00.Exerciese.2022]\C>k
100 10
91 92 93 94 95 96 97 98 99 100 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73  74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
D:\[00.Exerciese.2022]\C>k
6 2
5 6 1 2 3 4
D:\[00.Exerciese.2022]\C>k
100 99
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84  85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 1
D:\[00.Exerciese.2022]\C>

          这个代码也是整体只移动了一次。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-3-4 18:33:42 | 显示全部楼层
本帖最后由 jackz007 于 2022-3-4 22:58 编辑
#include <stdio.h>
int main(void)
{
        int a[100] , i , m , n                                          ;
        scanf("%d%d", & n , & m)                                        ;
        if(m < n) {
                for(i = 0 ; i < n ; i ++) a[i] = ((n - m + i) % n ) + 1 ;
                for(i = 0 ; i < n ; i ++) {
                        if(i) printf(" ")                               ;
                        printf("%d" , a[i])                             ;
                }
                printf("\n")                                            ;
        }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-4 18:56:56 | 显示全部楼层

啥原理?求教。貌似只对从0开始递增的数列有用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-4 19:19:52 | 显示全部楼层
a327904410 发表于 2022-3-4 18:56
啥原理?求教。貌似只对从0开始递增的数列有用

      其实就是按题目要求直接对数组赋值了而已,题目中不是要求尽可能少移动吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-4 19:41:26 | 显示全部楼层
本帖最后由 jackz007 于 2022-3-4 19:47 编辑
a327904410 发表于 2022-3-4 18:56
啥原理?求教。貌似只对从0开始递增的数列有用


        下面这个代码是真的对数组元素有移动,而且,所有元素只移动一次。
#include <stdio.h>
#include <stdlib.h>

void move(int d[] , int n , int m)
{
        int i , * p                                                                   ;
        if(n > m) {
                if(p = (int *) malloc(sizeof(int) * m)) {                               // 动态申请一个能够保存 m 个整型元素的存储空间 p[]
                        for(i = 0 ; i < m ; i ++) p[i] = d[n - m + i]                 ; // 先把数组 d[] 尾部即将被覆盖的 m 个元素全部保存到数组 p[] 中
                        for(i = 0 ; i < n - m ; i ++) d[n - 1 - i] = d[n - m - 1 - i] ; // 数组 d[0] - d[n - m - 1] 整体向后平移 m 个元素
                        for(i = 0 ; i < m ; i ++) d[i] = p[i]                         ; // 把 p[] 中的 m 个元素写入数组 d[] 从索引 0 开始的 m 个元素空间
                        free(p)                                                       ; // 释放动态申请的存储空间 p[]
                }
        }
}

int main(void)
{
        int a[100] , i , m , n                                                        ;
        scanf("%d%d" , & n , & m)                                                     ;
        if(n > m && m > 0) {
                for(i = 0 ; i < n ; i ++) a[i] = i + 1                                ;
                move(a , n , m)                                                       ;
                for(i = 0 ; i < n ; i ++) {
                        if(i) printf(" ")                                             ;
                        printf("%d" , a[i])                                           ;
                }
        }
}


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-4 22:24:04 | 显示全部楼层
jackz007 发表于 2022-3-4 19:19
其实就是按题目要求直接对数组赋值了而已,题目中不是要求尽可能少移动吗?

知道,就是中间的 for 循环 k 的值又恰好是最后排列的结果,感觉很神奇
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-4 22:51:48 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2022-3-5 00:24 编辑
a327904410 发表于 2022-3-4 22:24
知道,就是中间的 for 循环 k 的值又恰好是最后排列的结果,感觉很神奇


       没有什么好神奇的,当 n = 6 的时候,a[] = {1 , 2 , 3 , 4 , 5 , 6},如果 m = 2,那么,经过移动以后的 a[] = {5 , 6 , 1 , 2 , 3 , 4},只要确定移动后的 a[0] = 5,那么,就按从小到大依序向 a[] 中填入 6 个数值,a[] = {5 , 6 , 7 , 8 , 9 , 10},但是,我们知道,a[] 中没有数值超过 6 的元素,所以,还需要为所有数值超过 6 的元素减掉 6 ,这样,我们就得到了 a[] = {5 , 6 , 1 , 2 , 3 , 4}。
       2 楼的代码已经重新优化,与本解题思路相一致。

       下面是递归函数版本的代码
#include <stdio.h>

void move(int d[] , int n , int m , int c)
{
        int i , k                                                                     ;
        if(n > m) {
                if(c < m) {
                        k = d[n - m + c]                                              ;
                        move(d , n , m , c + 1)                                       ;
                        d[c] = k                                                      ;
                } else {
                        for(i = 0 ; i < n - m ; i ++) d[n - 1 - i] = d[n - m - 1 - i] ;
                }
        }
}

int main(void)
{
        int a[100] , i , m , n                                                        ;
        scanf("%d%d" , & n , & m)                                                     ;
        if(n > m && m > 0) {
                for(i = 0 ; i < n ; i ++) a[i] = i + 1                                ;
                move(a , n , m , 0)                                                   ;
                for(i = 0 ; i < n ; i ++) {
                        if(i) printf(" ")                                             ;
                        printf("%d" , a[i])                                           ;
                }
        }
}
        编译、运行实况
D:\[00.Exerciese.2022]\C>g++ -o k k.c

D:\[00.Exerciese.2022]\C>k
100 10
91 92 93 94 95 96 97 98 99 100 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73  74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
D:\[00.Exerciese.2022]\C>k
6 2
5 6 1 2 3 4
D:\[00.Exerciese.2022]\C>k
100 99
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84  85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 1
D:\[00.Exerciese.2022]\C>

          这个代码也是整体只移动了一次。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-3-5 11:06:57 | 显示全部楼层

但是好像缺少了题目的第二行要求,就是自己输入1,2,3,4,5,6这六个数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-5 11:12:37 | 显示全部楼层
本帖最后由 jackz007 于 2022-3-5 11:19 编辑
xhynb 发表于 2022-3-5 11:06
但是好像缺少了题目的第二行要求,就是自己输入1,2,3,4,5,6这六个数


        抱歉,审题不够严谨,下面的代码已经修改
#include <stdio.h>

void move(int d[] , int n , int m , int c)
{
        int i , k                                                                     ;
        if(n > m) {
                if(c < m) {
                        k = d[n - m + c]                                              ;
                        move(d , n , m , c + 1)                                       ;
                        d[c] = k                                                      ;
                } else {
                        for(i = 0 ; i < n - m ; i ++) d[n - 1 - i] = d[n - m - 1 - i] ;
                }
        }
}

int main(void)
{
        int a[100] , i , m , n                                                        ;
        scanf("%d%d" , & n , & m)                                                     ;
        if(n > m && m > 0) {
                for(i = 0 ; i < n ; i ++) scanf("%d" , & a[i])                        ;
                move(a , n , m , 0)                                                   ;
                for(i = 0 ; i < n ; i ++) {
                        if(i) printf(" ")                                             ;
                        printf("%d" , a[i])                                           ;
                }
                printf("\n")                                                          ;
        }
}
        编译、运行实况
D:\[00.Exerciese.2022]\C>g++ -o k k.c

D:\[00.Exerciese.2022]\C>k
6 2
6 5 4 3 2 1
2 1 6 5 4 3

D:\[00.Exerciese.2022]\C>k
6 2
1 3 5 2 4 6
4 6 1 3 5 2

D:\[00.Exerciese.2022]\C>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2022-3-6 13:47:14 | 显示全部楼层
jackz007 发表于 2022-3-4 22:51
没有什么好神奇的,当 n = 6 的时候,a[] = {1 , 2 , 3 , 4 , 5 , 6},如果 m = 2,那么,经过 ...

感谢教导
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-3-7 23:42:12 | 显示全部楼层
jackz007 发表于 2022-3-5 11:12
抱歉,审题不够严谨,下面的代码已经修改

        编译、运行实况

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-18 08:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表