Problem:
タイル (Tile)

問題

JOI 高校では， 1 × 1 の正方形のタイルを使って N × N の正方形の壁画を作り，文化祭で展示することになった．タイルの色は，赤，青，黄の 3 種類である．壁画のデザインは次の通りである．まず，最も外側の周に赤のタイルを貼り，その内側の周に青のタイルを貼る．さらにその内側の周に黄色のタイルを貼る．これを N × N の正方形が埋め尽くされるまで繰り返す．用いるタイルの色は，一番外側の周から順番に赤，青，黄，赤，青，黄，…である．

文化祭が近づいてきたある日，壁画のうち K 枚のタイルがはがれていることが判明した．そこで，新しいタイルを購入して，はがれた箇所に新しいタイルを貼ることにした．

入力として壁画の一辺の長さ N と，はがれたタイルの枚数 K， K 枚のはがれたタイルの位置が与えられたとき，はがれたタイルの色を求めるプログラムを作成せよ．

例えば，N = 11 の場合，11 × 11 の壁画のデザインは下図の通りである．

また，N = 16 の場合，16 × 16 の壁画のデザインは下図の通りである．

入力

入力は全部で 2+K 行からなる． 1 行目には，壁画の一辺の長さ N （1 ≤ N ≤ 1000000000 = 109）が， 2 行目には，はがれたタイルの枚数 K （1 ≤ K ≤ 1000）が書かれている． 2+i 行目（1 ≤ i ≤ K）には，2 つの整数 ai と bi （1 ≤ ai ≤ N, 1 ≤ bi ≤ N）が空白区切りで書かれており， i 枚目のはがれたタイルが，左から ai 列目，上から bi 行目のタイルであることを表す．

入力の 3 行目から 2+K 行目には同じタイルを表す行が重複して現れることはない．また，与えられる入力データ 40% では， N ≤ 1000 をみたしている．

出力

出力は K 行からなる．各行は 1 つの整数からなり， i 行目（1 ≤ i ≤K）の整数は，i 枚目のはがれたタイルが赤のときは 1 を，青のときは 2 を，黄色のときは 3 を表す．

入出力例

入力例 1

11
4
5 2
9 7
4 4
3 9

出力例 1

2
3
1
3

入力例 2

16
7
3 7
5 2
11 6
15 2
9 7
8 12
15 16

出力例 2

3
2
3
2
1
2
1

問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in Haskell (judge verdict: Accepted)

import Control.Applicative
import Control.Monad
import Control.Monad.ST
import Data.Functor
import Data.Function
import Data.Monoid
import Data.Maybe
import Data.List
import qualified Data.Foldable as Foldable
import qualified Data.Set as Set
import Data.List.Split
import Data.Bits
import Data.Char
import Data.Ix
import Data.Ratio
import Data.Ord
import Data.Tuple
import Data.Array
--import Data.Array.Unboxed
import Data.Array.IO
import Data.Array.ST
import Data.IORef
import Data.STRef
-- import System.IO.Unsafe
 
readInt = read :: String -> Int
readDouble = read :: String -> Double
getInt = readLn :: IO Int
getInts = map readInt . words <$> getLine
getDouble = readLn :: IO Double
sjoin :: (Show a) => [a] -> String
sjoin = unwords . map show
cond :: a -> a -> Bool -> a
cond t f c = if c then t else f
apply2 :: (a -> a -> b) -> [a] -> b
apply2 f [x,y] = f x y
apply3 :: (a -> a -> a -> b) -> [a] -> b
apply3 f [x,y,z] = f x y z
apply4 :: (a -> a -> a -> a -> b) -> [a] -> b
apply4 f [x,y,z,w] = f x y z w
fnBin :: (b -> c -> d) -> (a -> b) -> (a -> c) -> a -> d
fnBin op f g x = op (f x) $ g x
fnTuple :: (a -> b, a -> c) -> a -> (b, c)
fnTuple (f,g) a = (f a, g a)
replace :: (Eq a) => a -> a -> [a] -> [a]
replace x y = map (\z -> if z==x then y else z)
modifyArray :: (Ix i, MArray a e m) => a i e -> i -> (e -> e) -> m ()
modifyArray arr ix f = readArray arr ix >>= writeArray arr ix . f
-- end of templete

f n t = min t (n-1-t)

main = do
    n <- getInt
    k <- getInt
    replicateM k getInts >>= mapM_ (print . (+1) . (`mod` 3) . minimum . map (f n . (subtract 1)))