数码问题 (Standard IO)
题意/Description:
Alice有一个N*N的格子,把1-N^2按照从上到下从左到右的顺序填进表格中,允许在表格上进行两种操作:
(1)旋转行——这一行的数向右移动一个位置,而最后一列的数会移到第一列;
(2)旋转列——这一列的数向下移动一个位置,最后一行的数会移到第一行。
Alice想把数X移到(R,C)处可以采用以下方法:
如果X不在C这一列,通过旋转行操作把X移到C这一列;
如果X不在R这一行,通过旋转列操作把X移到R这一行。下面是一个把6移到(3,4)的例子:
Alice现在想采用上述方法,依次把K个数移到各自的目标位置,编程计算每个数需要几次操作。
读入/Input:
第一行包含两个整数N(12<=N<=10000)和K(1<=K<=1000)。
接下来K行,每行包含三个整数X(1<=X<=N^2)、R和C(1<=R,C<=N),描述需要移动的数以及目标位置。
Alice必须按照输入顺序依次移动。
输出/Output:
输出K行,每行输出一个整数,表示操作次数。
题解/solution:
首先,第一个数大家肯定会做。大家把这个数所在的行数记录下来,移动了多少,然后把要到达的点的列数记录下来,移动了多少。之后读入的数,把前面暴力一下,看看那些与之后的点有关,得出点的位置。总而言之,就是一个优美的暴力。之后就帮我点个赞吧,提提建议。
代码/Code:
var
n,k:longint;
x,y,xx,yy:array [0..100001] of longint;
procedure init;
var
i,j,o,p,z:longint;
begin
readln(n,k);
for i:=1 to k do
begin
readln(z,x[i],y[i]);
o:=z div n;
if z mod n=0 then p:=n else
begin
o:=o+1;
p:=z mod n;
end;
for j:=1 to i-1 do
begin
if x[j]=o then p:=(p+xx[j]) mod n;
if p=0 then p:=n;
if y[j]=p then o:=(o+yy[j]) mod n;
if o=0 then o:=n;
end;
if y[i]<p then xx[i]:=y[i]+n-p else xx[i]:=y[i]-p;
if x[i]<o then yy[i]:=x[i]+n-o else yy[i]:=x[i]-o;
x[i]:=o;
writeln(xx[i]+yy[i]);
end;
end;
begin
init;
end.