题目描述
编写一个程序,将1~n2按行依次填入n×n的矩阵,执行若干条行或者列的循环移动的指令,再将数字按行依次取出。
指令如下:
指令 | 含义 |
---|---|
L x y | x行循环左移y次 |
R x y | x行循环右移y次 |
U x y | x列循环上移y次 |
D x y | x列循环下移y次 |
输入
第一行是一个整数K,表示样例的个数。 每个样例的第一行是两个整数n(1≤n≤10)和m(1≤m≤1000),分别表示矩阵的大小和指令的条数。
以后的m行是m条指令,矩阵的行列按1开始计数,指令满足1≤x≤n,1≤y≤n−1。
输出
每行输出一个样例的结果,数字之间用一个空格隔开,行末无空格。
样例输入
4 3 1 L 1 1 3 1 R 1 1 3 1 U 1 1 3 1 D 1 1
样例输出
2 3 1 4 5 6 7 8 9 3 1 2 4 5 6 7 8 9 4 2 3 7 5 6 1 8 9 7 2 3 1 5 6 4 8 9
解这道题关键在于循环移动,循环移动可以采用下面的方法:
将一行循环左移n位,首先将第一位到第n位首尾交换,然后将第n+1位到最后一位首尾交换,
最后将交换后的第一位到最后一位首位交换。经此操作后即可得到循环左移后的一行。
其他循环同理。
然后分别定义循环移动的函数即可。
#include<stdio.h>
int num[12][12];
void swap1(int i,int a,int b)//a为首位,b为末位
{//交换行,i表示哪一列
int temp;
while(a<=b)
{
temp = num[a][i];
num[a][i] = num[b][i];
num[b][i] = temp;
a++,b--;
}
}
void swap2(int j,int x,int y)
{//交换列,j表示哪一行
int temp;
while(x<=y)
{
temp = num[j][x];
num[j][x] = num[j][y];
num[j][y] = temp;
x++,y--;
}
}
void left(int n,int x ,int y)
{
swap2(x,1,y);
swap2(x,y+1,n);
swap2(x,1,n);
}
void right(int n,int x,int y)
{
swap2(x,1,n-y);
swap2(x,n-y+1,n);
swap2(x,1,n);
}
void up(int n,int x,int y)
{
swap1(x,1,y);
swap1(x,y+1,n);
swap1(x,1,n);
}
void down(int n,int x,int y)
{
swap1(x,1,n-y);
swap1(x,n-y+1,n);
swap1(x,1,n);
}
int main()
{
int i,j,a,k,n,m,x,y;
char ch;
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&n,&m);
a=1;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
num[i][j]=a;
a++;
}
}
while(m--)
{
getchar();//回车也是字符,会影响
scanf("%c%d%d",&ch,&x,&y);
switch(ch)
{
case 'L':
left(n,x,y);
break;
case 'R':
right(n,x,y);
break;
case 'U':
up(n,x,y);
break;
case 'D':
down(n,x,y);
break;
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(j==n&&i==n)
{
printf("%d\n",num[i][j]);//保证行末无空格
break;
}
printf("%d ",num[i][j]);
}
}
}
return 0;
}