結果

問題 No.226 0-1パズル
ユーザー sansaquasansaqua
提出日時 2019-09-11 19:06:53
言語 Common Lisp
(sbcl 2.3.8)
結果
AC  
実行時間 12 ms / 5,000 ms
コード長 6,637 bytes
コンパイル時間 1,059 ms
コンパイル使用メモリ 60,688 KB
実行使用メモリ 22,784 KB
最終ジャッジ日時 2024-07-26 14:24:44
合計ジャッジ時間 1,940 ms
ジャッジサーバーID
(参考情報)
judge4 / judge2
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 8 ms
22,528 KB
testcase_01 AC 9 ms
22,400 KB
testcase_02 AC 9 ms
22,528 KB
testcase_03 AC 9 ms
22,528 KB
testcase_04 AC 9 ms
22,400 KB
testcase_05 AC 9 ms
22,528 KB
testcase_06 AC 9 ms
22,528 KB
testcase_07 AC 9 ms
22,528 KB
testcase_08 AC 9 ms
22,400 KB
testcase_09 AC 9 ms
22,400 KB
testcase_10 AC 8 ms
22,528 KB
testcase_11 AC 9 ms
22,400 KB
testcase_12 AC 8 ms
22,528 KB
testcase_13 AC 8 ms
22,272 KB
testcase_14 AC 9 ms
22,528 KB
testcase_15 AC 9 ms
22,400 KB
testcase_16 AC 9 ms
22,528 KB
testcase_17 AC 10 ms
22,656 KB
testcase_18 AC 11 ms
22,784 KB
testcase_19 AC 12 ms
22,784 KB
testcase_20 AC 11 ms
22,656 KB
testcase_21 AC 12 ms
22,656 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
; compiling file "/home/judge/data/code/Main.lisp" (written 26 JUL 2024 02:24:42 PM):

; wrote /home/judge/data/code/Main.fasl
; compilation finished in 0:00:00.113

ソースコード

diff #

;; -*- coding: utf-8 -*-
(eval-when (:compile-toplevel :load-toplevel :execute)
  (sb-int:defconstant-eqx OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0))
    #'equal)
  #+swank (ql:quickload '(:cl-debug-print :fiveam) :silent t)
  #-swank (set-dispatch-macro-character
           #\# #\> (lambda (s c p) (declare (ignore c p)) (read s nil nil t))))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)
#-swank (disable-debugger) ; for CS Academy

;; BEGIN_INSERTED_CONTENTS
;; from alexandria
(defun copy-array (array &key (element-type (array-element-type array))
                              (fill-pointer (and (array-has-fill-pointer-p array)
                                                 (fill-pointer array)))
                              (adjustable (adjustable-array-p array)))
  "Returns an undisplaced copy of ARRAY, with same fill-pointer and
adjustability (if any) as the original, unless overridden by the keyword
arguments."
 (let* ((dimensions (array-dimensions array))
        (new-array (make-array dimensions
                               :element-type element-type
                               :adjustable adjustable
                               :fill-pointer fill-pointer)))
   (dotimes (i (array-total-size array))
     (setf (row-major-aref new-array i)
           (row-major-aref array i)))
   new-array))

(declaim (inline read-line-into))
(defun read-line-into (buffer-string &key (in *standard-input*) (term-char #\Space))
  "Receives ASCII inputs and returns multiple values: the string and the end
position.

This function calls READ-BYTE to read characters though it calls READ-CHAR
instead on SLIME because SLIME's IO is not bivalent."
  (declare (inline read-byte)) ; declaring (sb-kernel:ansi-stream in) will be faster
  (loop for c of-type base-char =
           #-swank (code-char (read-byte in nil #.(char-code #\Newline)))
           #+swank (read-char in nil #\Newline)
        for idx from 0
        until (char= c #\Newline)
        do (setf (char buffer-string idx) c)
        finally (when (< idx (length buffer-string))
                  (setf (char buffer-string idx) term-char))
                (return (values buffer-string idx))))

(defmacro dbg (&rest forms)
  #+swank
  (if (= (length forms) 1)
      `(format *error-output* "~A => ~A~%" ',(car forms) ,(car forms))
      `(format *error-output* "~A => ~A~%" ',forms `(,,@forms)))
  #-swank (declare (ignore forms)))

(defmacro define-int-types (&rest bits)
  `(progn
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "UINT~A" b)) () '(unsigned-byte ,b))) bits)
     ,@(mapcar (lambda (b) `(deftype ,(intern (format nil "INT~A" b)) () '(signed-byte ,b))) bits)))
(define-int-types 2 4 7 8 15 16 31 32 62 63 64)

(declaim (inline println))
(defun println (obj &optional (stream *standard-output*))
  (let ((*read-default-float-format* 'double-float))
    (prog1 (princ obj stream) (terpri stream))))

(defconstant +mod+ 1000000007)

;;;
;;; Body
;;;
;;;
;;; Arithmetic operations with static modulus
;;;

(defmacro define-mod-operations (&optional (divisor 1000000007))
  `(progn
     (defun mod* (&rest args)
       (reduce (lambda (x y) (mod (* x y) ,divisor)) args))

     (sb-c:define-source-transform mod* (&rest args)
       (if (null args)
           1
           (reduce (lambda (x y) `(mod (* ,x ,y) ,',divisor)) args)))

     (defun mod+ (&rest args)
       (reduce (lambda (x y) (mod (+ x y) ,divisor)) args))

     (sb-c:define-source-transform mod+ (&rest args)
       (if (null args)
           0
           (reduce (lambda (x y) `(mod (+ ,x ,y) ,',divisor)) args)))

     (define-modify-macro incfmod (delta divisor)
       (lambda (x y divisor) (mod (+ x y) divisor)))

     (define-modify-macro decfmod (delta divisor)
       (lambda (x y divisor) (mod (- x y) divisor)))

     (define-modify-macro mulfmod (multiplier divisor)
       (lambda (x y divisor) (mod (* x y) divisor)))))

(define-mod-operations)

(defun fit-01-p (col mat)
  (loop for i below (array-dimension mat 0)
        for c = (aref mat i col)
        always (or (char= #\? c)
                   (if (evenp i)
                       (char= c #\0)
                       (char= c #\1)))))

(defun fit-10-p (col mat)
  (loop for i below (array-dimension mat 0)
        for c = (aref mat i col)
        always (or (char= #\? c)
                   (if (evenp i)
                       (char= c #\1)
                       (char= c #\0)))))

(defun solve (h w plan)
  (declare (uint31 h w))
  (let ((dp (copy-array plan))
        (res 0))
    (declare (uint31 res)
             ((simple-array base-char (* *)) dp))
    ;; count non-flipping
    (block non-flipping
      (dotimes (i h)
        (dotimes (j w)
          (let ((pivot (aref dp i j)))
            (unless (char= pivot #\?)
              (loop for k from (+ j 1) below w
                    for c = (if (char= #\0 (aref dp i (- k 1)))
                                #\1
                                #\0)
                    do (when (or (and (char= c #\0) (char= (aref dp i k) #\1))
                                 (and (char= c #\1) (char= (aref dp i k) #\0)))
                         (return-from non-flipping))
                       (setf (aref dp i k) c))
              (loop for k from (- j 1) downto 0
                    for c = (if (char= #\0 (aref dp i (+ k 1)))
                                #\1
                                #\0)
                    do (when (or (and (char= c #\0) (char= (aref dp i k) #\1))
                                 (and (char= c #\1) (char= (aref dp i k) #\0)))
                         (return-from non-flipping))
                       (setf (aref dp i k) c))))))
      (let ((freedom (loop for i below h count (char= #\? (aref dp i 0)))))
        (incfmod res (mod (expt 2 freedom) +mod+) +mod+)
        (when (fit-10-p 0 dp)
          (decfmod res 1 +mod+))
        (when (fit-01-p 0 dp)
          (decfmod res 1 +mod+))))
    ;; count flipping
    (let ((tmp 1))
      (declare (uint31 tmp))
      (dotimes (i w)
        (mulfmod tmp
                 (+ (if (fit-10-p i plan) 1 0)
                    (if (fit-01-p i plan) 1 0))
                 +mod+))
      (incfmod res tmp +mod+))
    res))

(defun main ()
  (let* ((h (read))
         (w (read))
         (plan (make-array (list h w) :element-type 'base-char :initial-element #\?))
         (line (make-string w :element-type 'base-char)))
    (dotimes (i h)
      (read-line-into line)
      (dotimes (j w)
        (setf (aref plan i j) (aref line j))))
    (println (solve h w plan))))

#-swank (main)
0