本题要求编写程序,将给定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,但不能解决%的移项,比如除移到右边是乘,但这个%我不知道……
后面想既然不可以,就直接输入时就进行排序。
所以只能先记录着,希望后面能想明白。