提出 #4625047


ソースコード 拡げる

;; -*- coding: utf-8 -*-
#-(or child-sbcl swank)
(quit
 :unix-status
 (process-exit-code
  (run-program *runtime-pathname*
               '("--control-stack-size" "32MB"
                 "--noinform" "--disable-ldb" "--lose-on-corruption" "--end-runtime-options"
                 "--eval" "(push :child-sbcl *features*)"
                 "--script" #.(namestring *load-pathname*))
               :output t :error t :input t)))


;; BEGIN_INSERTED_CONTENTS
(eval-when (:compile-toplevel :load-toplevel :execute)
  (defparameter OPT
    #+swank '(optimize (speed 3) (safety 2))
    #-swank '(optimize (speed 3) (safety 0) (debug 0)))
  #+swank (progn (ql:quickload '(:cl-debug-print :fiveam))
                 (shadow :run)
                 (use-package :fiveam)))
#+swank (cl-syntax:use-syntax cl-debug-print:debug-print-syntax)

(defmacro buffered-read-line (&optional (buffer-size 30) (in '*standard-input*) (terminate-char #\Space))
  "Note that the returned string will be reused."
  (let ((buffer (gensym))
        (character (gensym))
        (idx (gensym)))
    `(let ((,buffer (load-time-value (make-string ,buffer-size
                                                  :element-type 'base-char))))
       (declare (simple-base-string ,buffer))
       (loop for ,character 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= ,character #\Newline)
             do (setf (schar ,buffer ,idx) ,character)
             finally (when (< ,idx ,buffer-size)
                       (setf (schar ,buffer ,idx) ,terminate-char))
                     (return (values ,buffer ,idx))))))

(defmacro nlet (name args &body body)
  (labels ((ensure-list (x) (if (listp x) x (list x))))
    (let ((args (mapcar #'ensure-list args)))
      `(labels ((,name ,(mapcar #'car args) ,@body))
         (,name ,@(mapcar #'cadr args))))))


;; (with-memoizing (:hash-table :test #'equal :key #'cons)
;;   (defun ...))
;; (with-memoizing (:array (10 10 * 10) :initial-element -1 :element-type 'fixnum)
;;   (defun ...))
(defmacro with-memoizing (cache-attribs def-form)
  (let* ((cache-attribs (if (atom cache-attribs) (list cache-attribs) cache-attribs))
         (cache-type (first cache-attribs))
         (dimensions-with-* (when (eql cache-type :array) (second cache-attribs)))
         (dimensions (remove '* dimensions-with-*))
         (rank (length dimensions))
         (rest-attribs (ecase cache-type
                         (:hash-table (cdr cache-attribs))
                         (:array (cddr cache-attribs))))
         (key (prog1 (getf rest-attribs :key) (remf rest-attribs :key)))
         (cache-form (case cache-type
                       (:hash-table `(make-hash-table ,@rest-attribs))
                       (:array `(make-array (list ,@dimensions) ,@rest-attribs))))
         (initial-element (when (eql cache-type :array)
                            (assert (member :initial-element rest-attribs))
                            (getf rest-attribs :initial-element))))
    (let ((cache (gensym))
          (value (gensym))
	  (present-p (gensym))
          (name-alias (gensym))
	  (args-lst (gensym))
          (indices (loop repeat rank collect (gensym))))
      (labels ((make-cache-check-form (cache-type args)
                 (case cache-type
                   (:hash-table
                    `(let ((,args-lst (funcall ,(or key #'list) ,@args)))
                       (multiple-value-bind (,value ,present-p)
                           (gethash ,args-lst ,cache)
                         (if ,present-p
                             ,value
                             (setf (gethash ,args-lst ,cache)
                                   (,name-alias ,@args))))))
                   (:array
                    (let ((memoized-args (loop for dimension in dimensions-with-*
                                               for arg in args
                                               unless (eql dimension '*)
                                               collect arg)))
                      (if key
                          `(multiple-value-bind ,indices
                               (funcall ,key ,@memoized-args)
                             (let ((,value (aref ,cache ,@indices)))
                               (if (eql ,initial-element ,value)
                                   (setf (aref ,cache ,@indices)
                                         (,name-alias ,@args))
                                   ,value)))
                          `(let ((,value (aref ,cache ,@memoized-args)))
                             (if (eql ,initial-element ,value)
                                 (setf (aref ,cache ,@memoized-args)
                                       (,name-alias ,@args))
                                 ,value)))))))
               (make-reset-form (cache-type)
                 (case cache-type
                   (:hash-table `(setf ,cache (make-hash-table ,@rest-attribs)))
                   (:array `(prog1 nil
                              (fill (array-storage-vector ,cache) ,initial-element)))))
               (make-reset-name (name)
                 (intern (format nil "RESET-~A" (symbol-name name))))
               (extract-declarations (body)
                 (remove-if-not (lambda (form) (eql 'declare (car form))) body)))
        (ecase (car def-form)
          ((defun)
           (destructuring-bind (_ name args &body body) def-form
             (declare (ignore _))
             `(let ((,cache ,cache-form))
                (defun ,(make-reset-name name) () ,(make-reset-form cache-type))
                (defun ,name ,args
                  ,@(extract-declarations body)
                  (labels ((,name-alias ,args ,@body))
                    (declare (inline ,name-alias))
                    ,(make-cache-check-form cache-type args))))))
          ((nlet)
           (destructuring-bind (_ name bindings &body body) def-form
             (declare (ignore _))
             `(let ((,cache ,cache-form))
                (nlet ,name ,bindings
                  ,@(extract-declarations body)
                      ,(let ((args (mapcar (lambda (x) (if (atom x) x (car x))) bindings)))
                         `(labels ((,name-alias ,args ,@body))
                            (declare (inline ,name-alias))
                            ,(make-cache-check-form cache-type args)))))))
          ((labels flet)
           (destructuring-bind (_ definitions &body labels-body) def-form
             (declare (ignore _))
             (destructuring-bind (name args &body body) (car definitions)
               `(let ((,cache ,cache-form))
                  (,(car def-form)
                   ((,(make-reset-name name) () ,(make-reset-form cache-type))
                    (,name ,args
                           ,@(extract-declarations body)
                           (labels ((,name-alias ,args ,@body))
                             (declare (inline ,name-alias))
                             ,(make-cache-check-form cache-type args)))
                    ,@(cdr definitions))
                   (declare (ignorable #',(make-reset-name name)))
                   ,@labels-body))))))))))

;; (test with-memoizing
;;   (finishes (macroexpand `(with-memoizing (:hash-table :test #'equal)
;;                             (defun add (x y) (+ x y)))))
;;   (finishes (macroexpand `(with-memoizing (:array '(10 10)
;;                                            :element-type 'fixnum
;;                                            :initial-element -1)
;;                             (defun add (x y) (+ x y)))))
;;   (finishes (macroexpand `(with-memoizing (:array '(10 10)
;;                                            :element-type 'fixnum
;;                                            :initial-element -1)
;;                             (labels ((add (x y) (+ x y))
;; 		                     (my-print (x) (print x)))
;; 	                      (add 1 2))))))

(declaim (inline split-ints-into-vector))
(defun split-ints-into-vector (string dest-vector &key (offset 0) (key #'identity))
  (declare (string string)
           (function key)
           ((array * (*)) dest-vector)
           ((integer 0 #.most-positive-fixnum) offset))
  (loop with position = 0
        for idx from offset below (length dest-vector)
        do (setf (values (aref dest-vector idx) position)
                 (parse-integer string :start position :junk-allowed t))
           (setf (aref dest-vector idx) (funcall key (aref dest-vector idx)))
        finally (return dest-vector)))

(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)

(defmacro println (obj &optional (stream '*standard-output*))
  `(let ((*read-default-float-format* 'double-float))
     (prog1 (princ ,obj ,stream) (terpri ,stream))))

(defconstant +mod+ 1000000007)

;; Hauptteil

(defun main ()
  (declare #.OPT)
  (let* ((n (read))
         (stones (make-array n :element-type 'uint31)))
    (dotimes (i n) (setf (aref stones i) (- (parse-integer (buffered-read-line 6) :junk-allowed t) 1)))
    (let ((table (make-array n :element-type 'int32 :initial-element -1))
          (last-poses (make-array 200000 :element-type 'int32 :initial-element -1)))
      (loop with prev-color = -1
            for i from 0 below n
            do (let ((c (aref stones i)))
                 (if (= prev-color c)
                     (setf (aref table i) (aref table (- i 1)))
                     (setf (aref table i) (aref last-poses c)
                           (aref last-poses c) i
                           prev-color c))))
      (println
       (with-memoizing (:array (200000) :element-type 'int32 :initial-element -1)
         (nlet recur ((i (- n 1)))
           (cond ((zerop i) 1)
                 ((= (aref stones (- i 1)) (aref stones i))
                  (recur (- i 1)))
                 ((= -1 (aref table i))
                  (recur (- i 1)))
                 (t (mod (+ (recur (- i 1))
                            (recur (aref table i)))
                         +mod+)))))))))

#-swank(main)

提出情報

提出日時
問題 B - Reversi
ユーザ sansaqua
言語 Common Lisp (SBCL 1.1.14)
得点 700
コード長 10623 Byte
結果 AC
実行時間 368 ms
メモリ 55480 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 700 / 700
結果
AC × 3
AC × 33
セット名 テストケース
Sample s1.txt, s2.txt, s3.txt
All 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt, 29.txt, 30.txt, s1.txt, s2.txt, s3.txt
ケース名 結果 実行時間 メモリ
01.txt AC 368 ms 55480 KiB
02.txt AC 164 ms 39992 KiB
03.txt AC 163 ms 39992 KiB
04.txt AC 163 ms 39992 KiB
05.txt AC 143 ms 39992 KiB
06.txt AC 143 ms 39992 KiB
07.txt AC 143 ms 39992 KiB
08.txt AC 143 ms 39996 KiB
09.txt AC 129 ms 39992 KiB
10.txt AC 130 ms 39992 KiB
11.txt AC 128 ms 39992 KiB
12.txt AC 128 ms 39992 KiB
13.txt AC 160 ms 39996 KiB
14.txt AC 160 ms 39992 KiB
15.txt AC 158 ms 39992 KiB
16.txt AC 158 ms 39992 KiB
17.txt AC 158 ms 39988 KiB
18.txt AC 158 ms 39992 KiB
19.txt AC 158 ms 39988 KiB
20.txt AC 158 ms 39992 KiB
21.txt AC 156 ms 39988 KiB
22.txt AC 156 ms 39996 KiB
23.txt AC 124 ms 39992 KiB
24.txt AC 157 ms 39988 KiB
25.txt AC 96 ms 23608 KiB
26.txt AC 96 ms 23608 KiB
27.txt AC 96 ms 23608 KiB
28.txt AC 96 ms 23608 KiB
29.txt AC 96 ms 23612 KiB
30.txt AC 96 ms 23612 KiB
s1.txt AC 96 ms 23608 KiB
s2.txt AC 96 ms 23608 KiB
s3.txt AC 96 ms 23604 KiB