結果
| 問題 |
No.226 0-1パズル
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-09-11 19:08:24 |
| 言語 | Common Lisp (sbcl 2.5.0) |
| 結果 |
AC
|
| 実行時間 | 11 ms / 5,000 ms |
| コード長 | 6,804 bytes |
| コンパイル時間 | 205 ms |
| コンパイル使用メモリ | 54,536 KB |
| 実行使用メモリ | 22,784 KB |
| 最終ジャッジ日時 | 2024-07-26 14:24:47 |
| 合計ジャッジ時間 | 1,064 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 22 |
コンパイルメッセージ
; compiling file "/home/judge/data/code/Main.lisp" (written 26 JUL 2024 02:24:45 PM): ; file: /home/judge/data/code/Main.lisp ; in: DEFUN SOLVE ; (EXPT 2 FREEDOM) ; ; note: forced to do full call ; unable to do inline ASH (cost 3) because: ; The result is a (VALUES (INTEGER 1) &OPTIONAL), not a (VALUES FIXNUM ; &OPTIONAL). ; unable to do inline ASH (cost 4) because: ; The result is a (VALUES (INTEGER 1) &OPTIONAL), not a (VALUES ; (UNSIGNED-BYTE 64) ; &OPTIONAL). ; etc. ; ; compilation unit finished ; printed 1 note ; wrote /home/judge/data/code/Main.fasl ; compilation finished in 0:00:00.082
ソースコード
;; -*- 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)
(declare #.OPT
((simple-array base-char (* *)) 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)
(declare #.OPT
((simple-array base-char (* *)) 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 #.OPT
(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 ()
(declare #.OPT)
(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)