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行,每行输出一个整数,表示操作次数。
Sample Input
输入1: 4 1 6 3 4 输入2: 4 2 6 3 4 6 2 2 输入3: 5 3 1 2 2 2 2 2 12 5 5
Sample Output
输出1: 3 输出2: 3 5 输出3: 2 5 3
Data Constraint
正解
看范围就知道,一个个模拟状态肯定是过不了的。我们可以想到,不管怎么移,他所在的那一行、那一列的数都不会改变(只是顺序变了而已)。所以,我们不用枚举,直接维护一下他的行和列就行了。
CODE
var
n,m,i,j,k,x,y:longint;
lie,hang,r,c:array[1..1001]of longint;
begin
readln(n,m);
for i:=1 to m do begin
readln(k,r[i],c[i]);
x:=k div n;
y:=k mod n;
if y=0 then
y:=n
else
inc(x);
for j:=1 to i-1 do begin
if r[j]=x then
y:=(y+lie[j]) mod n;
if y=0 then y:=n;
if c[j]=y then
x:=(x+hang[j]) mod n;
if x=0 then x:=n;
end;
lie[i]:=c[i]-y;
if lie[i]<0 then
lie[i]:=lie[i]+n;
hang[i]:=r[i]-x;
if hang[i]<0 then
hang[i]:=hang[i]+n;
r[i]:=x;
writeln(lie[i]+hang[i]);
end;
end.