Official

C - Reorder Cards Editorial by kyopro_friends


行に関する操作と列に関する操作は互いに干渉しません。そのため行と列について独立に考えることができます。以下では上から何行目かについて考えますが、左から何列目かも同様に求めることができます。

まず、操作によってカード同士の位置関係(どちらがより上にあるか、など)が変わることはありません。また、操作終了後には全ての行・列が数の書かれたカードを含みます。
このことから、操作終了後には、もともと最も上にあった数の書かれたカードが1行目に、2番目に上にあった数の書かれたカードが2行目に、……となることがわかります。

したがって元の問題は「\(A_i\) たちを、大小関係を保ったまま、値を小さくせよ」と読み替えることができました。 例えば \(A=(2,9,9,7,9,2,4)\) であれば \((1,4,4,3,4,1,2)\) に変換せよ、という意味です。

これは「座標圧縮」と呼ばれる操作にほかなりません。したがって \(O(N\log N)\) で問題が解けました。具体的な実装方法については各自で調べてください。

実装例(Python)

H,W,N=map(int,input().split())
X,Y=[],[]
for i in range(N):
  x,y=map(int,input().split())
  X.append(x)
  Y.append(y)

Xdict = {x:i+1 for i,x in enumerate(sorted(list(set(X))))}
Ydict = {y:i+1 for i,y in enumerate(sorted(list(set(Y))))}

for i in range(N):
  print(Xdict[X[i]], Ydict[Y[i]])

posted:
last update: