练习7-8 方阵循环右移 (20分)

本题要求编写程序,将给定n×n方阵中的每个元素循环向右移m个位置,即将第0、1、⋯、n−1列变换为第n−m、n−m+1、⋯、n−1、0、1、⋯、n−m−1列。ps.不用看这个n-m、n-m+1……我反正没看出有什么用,可能我8行吧。

输入格式:
输入第一行给出两个正整数m和n(1≤n≤6)。接下来一共n行,每行n个整数,表示一个n阶的方阵。

输出格式:
按照输入格式输出移动后的方阵:即输出n行,每行n个整数,每个整数后输出一个空格。

输入样例:

2 3

1 2 3

4 5 6

7 8 9

输出样例:

2 3 1

5 6 4

8 9 7

#include<stdio.h>
int main()
{
//输入
    int m,n,a[6][6];
    scanf("%d %d",&m,&n);
    m=m%n;//移动是周期性的,比如m=5时和m=8,移动后的排序是一样的,有效移动是m%n,当然这步也可以不写,但运行时间相对写了的有点长;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++) scanf("%d",*(a+i)+j);
//操作    
    for(int i=0;i<n;i++)
    {
        for(int j=1;j<=m;j++)//控制向右移动次数
        {
            int t=a[i][n-1];
            for(int k=n-2;k>=0;k--)//每个数字覆盖后面的数,从倒数第二项开始覆盖
                a[i][k+1]=a[i][k];
            a[i][0]=t;
        }
    }
//输出
   for(int i=0;i<n;i++)
    { for(int j=0;j<n;j++) printf("%d ",*(*(a+i)+j));printf("\n");}
    return 0;
}

回顾的时候,我想到了新的东西,因为上面的东西我觉得不够高大上,代码写得多,曾经看到过一个大佬用了(n-m+j)%n,完美的解决了问题,我也想让我的代码有更多的那个“数学”的味道,但这个式子我还是不知道怎么推导出来的……
但是,我也想到了我的另外一个思路,即,在输入数据时就用(j+m)%n进行排序。

#include<stdio.h>
int main()
{
    int m,n,a[6][6];
    scanf("%d %d",&m,&n);
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++) 
        scanf("%d",*(a+i)+(j+m)%n);
    for(int i=0;i<n;i++)
    { 
        for(int j=0;j<n;j++) 
    		printf("%d ",*(*(a+i)+j));
    	printf("\n");
    }
    return 0;
}

关于那个公式(n-m+j)%n的代码如下

#include<stdio.h>
int main()
{
    int m,n,a[6][6];
    scanf("%d %d",&m,&n);
    m%=n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++) 
        scanf("%d",*(a+i)+j);
    for(int i=0;i<n;i++)
    { 
        for(int j=0;j<n;j++) 
    		printf("%d ",*(*(a+i)+(n-m+j)%n));
    	printf("\n");
    }
    return 0;
}

我一开始想着,逆推用列方程,比如(x+m)%n=j(m为m%=n),通过这个式子解出x,但不能解决%的移项,比如除移到右边是乘,但这个%我不知道……
后面想既然不可以,就直接输入时就进行排序。
所以只能先记录着,希望后面能想明白。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值