Permalink
Browse files

GCJ round 1 B.

  • Loading branch information...
nbeloglazov committed May 6, 2012
1 parent 6b9883d commit 3f68d49327ec862520a50e6d2e093d18ed428133
View
@@ -1,2 +0,0 @@
-1
-1 100000
View
@@ -1 +0,0 @@
-Case #1: 215925
View
@@ -1,3 +1,4 @@
(defproject gcj2012 "1.0.0-SNAPSHOT"
:description "FIXME: write description"
- :dependencies [[org.clojure/clojure "1.3.0"]])
+ :dependencies [[org.clojure/clojure "1.4.0"]
+ [org.clojure/math.combinatorics "0.0.2"]])
View
@@ -0,0 +1,209 @@
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.util.*;
+
+public class TaskB {
+
+ private class Cell implements Comparable<Cell> {
+ public int x, y;
+
+ private Cell(int y, int x) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public List<Cell> neighbours() {
+ List<Cell> result = new ArrayList<Cell>();
+ for (int i = -1; i < 2; i++) {
+ for (int j = -1; j < 2; j++) {
+ if ((i != 0) ^ (j != 0)) {
+ int newX = x + i;
+ int newY = y + j;
+ if (newX >= 0 && newX < m && newY >= 0 && newY < n) {
+ result.add(new Cell(newY, newX));
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ public int floor() {
+ return TaskB.this.floor[y][x];
+ }
+
+ public int ceiling() {
+ return TaskB.this.ceiling[y][x];
+ }
+
+ public boolean visited() {
+ return TaskB.this.visited[y][x];
+ }
+
+ public void visit() {
+ TaskB.this.visited[y][x] = true;
+ }
+
+ public boolean canVisitWithoutWater(Cell cell) {
+ return (cell.ceiling() - cell.floor() >= 50) && (cell.ceiling() - floor() >= 50) &&
+ (ceiling() - cell.floor() >= 50);
+ }
+
+ public boolean canVisit(Cell cell, double time) {
+ return canVisitWithoutWater(cell) && cell.ceiling() - level(time) >= 50;
+ }
+
+ public double whenCanVisit() {
+ return (50 - ceiling() + h) / 10.0;
+ }
+
+ public double speed(double time) {
+ return (level(time) - floor() >= 20) ? 1 : 10;
+ }
+
+ public double getTime() {
+ return time[y][x];
+ }
+
+ public double setTime(double time) {
+ return TaskB.this.time[y][x] = time;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Cell cell = (Cell) o;
+
+ if (x != cell.x) return false;
+ if (y != cell.y) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = x;
+ result = 31 * result + y;
+ return result;
+ }
+
+ public int compareTo(Cell o) {
+ return Double.compare(getTime(), o.getTime());
+ }
+ }
+
+ private int floor[][], ceiling[][];
+ private double time[][];
+ private boolean visited[][];
+ private int n,m;
+ private int h;
+ private Scanner scanner;
+ private PrintWriter printWriter;
+ private PriorityQueue<Cell> queue;
+
+ private double level(double time) {
+ return Math.max(h - 10 * time, 0);
+ }
+
+ private void relax(Cell from, Cell to) {
+ if (to.visited()) {
+ return;
+ }
+ if (from.canVisitWithoutWater(to)) {
+ double start = Math.max(from.getTime(), to.whenCanVisit());
+ double takes = start + from.speed(start);
+ if (to.getTime() == -1 || to.getTime() > takes) {
+ to.setTime(takes);
+ queue.add(to);
+ }
+ }
+ }
+
+ private void dijkstra() {
+ while (!visited[n-1][m-1]) {
+ Cell cell = queue.poll();
+ queue.remove(cell);
+ cell.visit();
+ for (Cell neib : cell.neighbours()) {
+ relax(cell, neib);
+ }
+ }
+ }
+
+ private void dfs(Cell cell) {
+ if (cell.visited()) {
+ return;
+ }
+ cell.visit();
+ cell.setTime(0);
+ for (Cell neib : cell.neighbours()) {
+ if (cell.canVisit(neib, 0)) {
+ dfs(neib);
+ } else {
+ relax(cell, neib);
+ }
+ }
+ }
+
+ private void readData() throws Exception {
+ h = scanner.nextInt();
+ n = scanner.nextInt();
+ m = scanner.nextInt();
+ floor = new int[n][m];
+ ceiling = new int[n][m];
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < m; j++) {
+ ceiling[i][j] = scanner.nextInt();
+ }
+ }
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < m; j++) {
+ floor[i][j] = scanner.nextInt();
+ }
+ }
+ time = new double[n][m];
+ for (double[] ar : time) {
+ Arrays.fill(ar, -1);
+ }
+ visited = new boolean[n][m];
+ queue = new PriorityQueue<Cell>();
+ }
+
+ private void outputResult(int i) throws Exception {
+ printWriter.printf("Case #%d: %.7f\n", i, time[n - 1][m - 1]);
+ }
+
+ private void runTest(int testNumber) throws Exception {
+ readData();
+ dfs(new Cell(0, 0));
+ dijkstra();
+ outputResult(testNumber);
+ }
+
+ private void runAll() throws Exception {
+ scanner = new Scanner(new File("input.txt"));
+ printWriter = new PrintWriter(new FileWriter("output.txt"));
+ int n = scanner.nextInt();
+ for (int i = 0; i < n; i++) {
+ runTest(i + 1);
+ }
+ printWriter.close();
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ new TaskB().runAll();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }.start(); ;
+ }
+}
@@ -1 +0,0 @@
-(ns gcj2012.core)
@@ -1,4 +1,4 @@
-(ns gcj2012.qualA)
+(ns gcj2012.qual.qualA)
(def pairs [["ejp mysljylc kd kxveddknmc re jsicpdrysi" "our language is impossible to understand"]
["rbcpc ypc rtcsra dkh wyfrepkym veddknkmkrkcd" "there are twenty six factorial possibilities"]
@@ -1,4 +1,4 @@
-(ns gcj2012.qualC)
+(ns gcj2012.qual.qualC)
(defn shift [num max]
(+ (* max (mod num 10))
@@ -0,0 +1,45 @@
+(ns gcj2012.round-1-b.taskA)
+
+(defn level? [s level sum]
+ (->> (map #(- level %) s)
+ (remove neg?)
+ (apply +)
+ (>= sum)))
+
+(defn find-level [s]
+ (let [sum (apply + s)]
+ (loop [left 0.0
+ right (* 2 sum)]
+ (if (> 1e-9 (- right left))
+ left
+ (let [mid (/ (+ left right) 2)]
+ (if (level? s mid sum)
+ (recur mid right)
+ (recur left mid)))))))
+
+(defn calc-prob [s]
+ (let [level (find-level s)
+ sum (apply + s)]
+ (map #(if (>= % level)
+ 0
+ (/ (- level %) sum 0.01)) s)))
+
+
+(defn parse-line [line]
+ (map #(Integer/parseInt %) (rest (.split line " "))))
+
+(defn seq-to-str [s]
+ (apply str (interpose " " s)))
+
+(defn solve []
+ (->> (slurp "input.txt")
+ (clojure.string/split-lines)
+ (rest)
+ (map parse-line)
+ (map calc-prob)
+ (map seq-to-str)
+ (map-indexed #(format "Case #%d: %s" (inc %1) %2))
+ (doall)
+ (interpose \newline)
+ (apply str)
+ (spit "output.txt")))
@@ -0,0 +1,36 @@
+(ns gcj2012.round-1-b.taskC
+ (:require [clojure.math.combinatorics :as comb]))
+
+(defn seq-to-str [s]
+ (apply str (interpose " " s)))
+
+(defn find-subsets [s]
+ (loop [subsets (comb/subsets s)
+ vals {}]
+ (if (empty? subsets)
+ "Impossible"
+ (let [nxt (first subsets)
+ sum (apply + nxt)]
+ (if (contains? vals sum)
+ (str (seq-to-str (vals sum))
+ "\n"
+ (seq-to-str nxt))
+ (recur (rest subsets)
+ (assoc vals sum nxt)))))))
+
+(defn parse-line [line]
+ (map #(Integer/parseInt %) (rest (.split line " "))))
+
+(defn solve []
+ (->> (slurp "input.txt")
+ (clojure.string/split-lines)
+ (rest)
+ (map parse-line)
+ (map find-subsets)
+ (map-indexed #(format "Case #%d: \n%s" (inc %1) %2))
+ (doall)
+ (interpose \newline)
+ (apply str)
+ (spit "output.txt")))
+
+

0 comments on commit 3f68d49

Please sign in to comment.