Submission #8339354


Source Code Expand

;; -*- 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
(declaim (inline relative-error-p))
(defun relative-error<= (x y threshold)
  "Returns true iff the relative error between X and Y is equal to or smaller
than THRESHOLD: i.e. the relative errors of any numbers in the interval [X,
Y] (or [Y, X]) are equal to or smaller than THRESHOLD assuming that the true
value is in the same interval."
  (and (not (zerop x))
       (not (zerop y))
       (<= (abs (/ (- x y) y)) threshold)
       (<= (abs (/ (- x y) x)) threshold)))

(defun error<= (x y threshold)
  "Returns true iff the relative or absolute error between X and Y is equal to
or smaller than threshold."
  (or (<= (abs (- x y)) threshold)
      (relative-error<= x y threshold)))

(declaim (ftype (function * (values fixnum &optional)) read-fixnum))
(defun read-fixnum (&optional (in *standard-input*))
  (macrolet ((%read-byte ()
               `(the (unsigned-byte 8)
                     #+swank (char-code (read-char in nil #\Nul))
                     #-swank (sb-impl::ansi-stream-read-byte in nil #.(char-code #\Nul) nil))))
    (let* ((minus nil)
           (result (loop (let ((byte (%read-byte)))
                           (cond ((<= 48 byte 57)
                                  (return (- byte 48)))
                                 ((zerop byte) ; #\Nul
                                  (error "Read EOF or #\Nul."))
                                 ((= byte #.(char-code #\-))
                                  (setf minus t)))))))
      (declare ((integer 0 #.most-positive-fixnum) result))
      (loop
        (let* ((byte (%read-byte)))
          (if (<= 48 byte 57)
              (setq result (+ (- byte 48)
                              (* 10 (the (integer 0 #.(floor most-positive-fixnum 10)) result))))
              (return (if minus (- result) result))))))))

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

(define-modify-macro minf (new-value) min)
(define-modify-macro maxf (new-value) max)

(defun feasible-p (xs ys cs threshold)
  (declare #.OPT
           ((simple-array double-float (*)) xs ys cs)
           (double-float threshold))
  (let ((n (length xs))
        (lx most-negative-double-float)
        (rx most-positive-double-float)
        (ly most-negative-double-float)
        (ry most-positive-double-float))
    (declare (double-float lx rx ly ry))
    (dotimes (i n)
      (let ((x (aref xs i))
            (y (aref ys i))
            (c (aref cs i)))
        (maxf lx (- x (* c threshold)))
        (minf rx (+ x (* c threshold)))
        (maxf ly (- y (* c threshold)))
        (minf ry (+ y (* c threshold)))))
    (and (<= lx rx) (<= ly ry))))

(defun main ()
  (let* ((n (read))
         (xs (make-array n :element-type 'double-float))
         (ys (make-array n :element-type 'double-float))
         (cs (make-array n :element-type 'double-float)))
    (dotimes (i n)
      (setf (aref xs i) (float (read-fixnum) 1d0)
            (aref ys i) (float (read-fixnum) 1d0)
            (aref cs i) (/ (float (read-fixnum) 1d0))))
    (sb-int:named-let bisect ((ng 1d-5) (ok 1d9))
      (if (relative-error<= ok ng 1d-6)
          (println ok)
          (let ((mid (* 0.5d0 (+ ng ok))))
            (if (feasible-p xs ys cs mid)
                (bisect ng mid)
                (bisect mid ok)))))))

#-swank (main)

;;;
;;; Test and benchmark
;;;

#+swank
(defun io-equal (in-string out-string &key (function #'main) (test #'equal))
  "Passes IN-STRING to *STANDARD-INPUT*, executes FUNCTION, and returns true if
the string output to *STANDARD-OUTPUT* is equal to OUT-STRING."
  (labels ((ensure-last-lf (s)
             (if (eql (uiop:last-char s) #\Linefeed)
                 s
                 (uiop:strcat s uiop:+lf+))))
    (funcall test
             (ensure-last-lf out-string)
             (with-output-to-string (out)
               (let ((*standard-output* out))
                 (with-input-from-string (*standard-input* (ensure-last-lf in-string))
                   (funcall function)))))))

#+swank
(defun get-clipbrd ()
  (with-output-to-string (out)
    (run-program "C:/msys64/usr/bin/cat.exe" '("/dev/clipboard") :output out)))

#+swank (defparameter *this-pathname* (uiop:current-lisp-file-pathname))
#+swank (defparameter *dat-pathname* (uiop:merge-pathnames* "test.dat" *this-pathname*))

#+swank
(defun run (&optional thing (out *standard-output*))
  "THING := null | string | symbol | pathname

null: run #'MAIN using the text on clipboard as input.
string: run #'MAIN using the string as input.
symbol: alias of FIVEAM:RUN!.
pathname: run #'MAIN using the text file as input."
  (let ((*standard-output* out))
    (etypecase thing
      (null
       (with-input-from-string (*standard-input* (delete #\Return (get-clipbrd)))
         (main)))
      (string
       (with-input-from-string (*standard-input* (delete #\Return thing))
         (main)))
      (symbol (5am:run! thing))
      (pathname
       (with-open-file (*standard-input* thing)
         (main))))))

#+swank
(defun gen-dat ()
  (uiop:with-output-file (out *dat-pathname* :if-exists :supersede)
    (format out "")))

#+swank
(defun bench (&optional (out (make-broadcast-stream)))
  (time (run *dat-pathname* out)))

;; To run: (5am:run! :sample)
#+swank
(it.bese.fiveam:test :sample
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "2
0 0 1
10 10 1
"
    "5.000000000000000
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "2
0 0 1
10 10 2
"
    "6.666666666666667
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "10
-27 -67 10
59 13 10
14 -15 9
-29 -84 7
-75 -2 2
-12 -74 5
77 31 9
40 64 8
-81 32 1
81 26 5
"
    "582.222222222222222
"))
  (it.bese.fiveam:is
   (common-lisp-user::io-equal "8
-81739 73917 446
42230 30484 911
79354 -50126 200
33440 -47087 651
-73 84114 905
79222 -53608 713
65194 -46284 685
81145 40933 47
"
    "54924095.383189122374461
")))

Submission Info

Submission Time
Task B - 高橋ノルム君
User sansaqua
Language Common Lisp (SBCL 1.1.14)
Score 100
Code Size 7313 Byte
Status AC
Exec Time 68 ms
Memory 14824 KiB

Judge Result

Set Name Sample Subtask1 Subtask2
Score / Max Score 0 / 0 30 / 30 70 / 70
Status AC
AC × 13
AC × 30
Set Name Test Cases
Sample
Subtask1 subtask1_01.txt, subtask1_02.txt, subtask1_03.txt, subtask1_04.txt, subtask1_05.txt, subtask1_06.txt, subtask1_07.txt, subtask1_08.txt, subtask1_09.txt, subtask1_10.txt, subtask1_11.txt, subtask1_12.txt, subtask1_13.txt
Subtask2 subtask0_sample_01.txt, subtask0_sample_02.txt, subtask0_sample_03.txt, subtask0_sample_04.txt, subtask1_01.txt, subtask1_02.txt, subtask1_03.txt, subtask1_04.txt, subtask1_05.txt, subtask1_06.txt, subtask1_07.txt, subtask1_08.txt, subtask1_09.txt, subtask1_10.txt, subtask1_11.txt, subtask1_12.txt, subtask1_13.txt, subtask2_01.txt, subtask2_02.txt, subtask2_03.txt, subtask2_04.txt, subtask2_05.txt, subtask2_06.txt, subtask2_07.txt, subtask2_08.txt, subtask2_09.txt, subtask2_10.txt, subtask2_11.txt, subtask2_12.txt, subtask2_13.txt
Case Name Status Exec Time Memory
subtask0_sample_01.txt AC 66 ms 14824 KiB
subtask0_sample_02.txt AC 66 ms 14820 KiB
subtask0_sample_03.txt AC 66 ms 14824 KiB
subtask0_sample_04.txt AC 66 ms 14824 KiB
subtask1_01.txt AC 66 ms 14820 KiB
subtask1_02.txt AC 66 ms 14820 KiB
subtask1_03.txt AC 66 ms 14820 KiB
subtask1_04.txt AC 66 ms 14820 KiB
subtask1_05.txt AC 66 ms 14820 KiB
subtask1_06.txt AC 66 ms 14820 KiB
subtask1_07.txt AC 68 ms 14820 KiB
subtask1_08.txt AC 67 ms 14820 KiB
subtask1_09.txt AC 66 ms 14820 KiB
subtask1_10.txt AC 67 ms 14816 KiB
subtask1_11.txt AC 66 ms 14824 KiB
subtask1_12.txt AC 67 ms 14820 KiB
subtask1_13.txt AC 66 ms 14824 KiB
subtask2_01.txt AC 66 ms 14820 KiB
subtask2_02.txt AC 66 ms 14824 KiB
subtask2_03.txt AC 66 ms 14820 KiB
subtask2_04.txt AC 66 ms 14820 KiB
subtask2_05.txt AC 67 ms 14824 KiB
subtask2_06.txt AC 66 ms 14820 KiB
subtask2_07.txt AC 66 ms 14820 KiB
subtask2_08.txt AC 66 ms 14820 KiB
subtask2_09.txt AC 66 ms 14820 KiB
subtask2_10.txt AC 66 ms 14816 KiB
subtask2_11.txt AC 66 ms 14820 KiB
subtask2_12.txt AC 66 ms 14816 KiB
subtask2_13.txt AC 66 ms 14824 KiB