zoukankan      html  css  js  c++  java
  • 有一种代码令人神往

      偶然看到Petr的AC代码,真的惊呆了,终于知道自己弱在哪里了,终于找到喜欢的风格了。

      1 import java.util.List;
      2 import java.io.IOException;
      3 import java.io.InputStreamReader;
      4 import java.util.Arrays;
      5 import java.util.ArrayList;
      6 import java.io.BufferedReader;
      7 import java.util.Comparator;
      8 import java.io.OutputStream;
      9 import java.io.PrintWriter;
     10 import java.util.Random;
     11 import java.util.StringTokenizer;
     12 import java.util.Collections;
     13 import java.io.InputStream;
     14 
     15 /**
     16  * Built using CHelper plug-in
     17  * Actual solution is at the top
     18  */
     19 public class Main {
     20     public static void main(String[] args) {
     21         InputStream inputStream = System.in;
     22         OutputStream outputStream = System.out;
     23         InputReader in = new InputReader(inputStream);
     24         PrintWriter out = new PrintWriter(outputStream);
     25         TaskE solver = new TaskE();
     26         solver.solve(1, in, out);
     27         out.close();
     28     }
     29 }
     30 
     31 class TaskE {
     32     static class Obstacle {
     33         int x;
     34         int y;
     35     }
     36 
     37     static class SumThenDiffComparator implements Comparator<Obstacle> {
     38         static final SumThenDiffComparator INSTANCE = new SumThenDiffComparator();
     39 
     40         public int compare(Obstacle o1, Obstacle o2) {
     41             int s1 = o1.x + o1.y;
     42             int s2 = o2.x + o2.y;
     43             if (s1 != s2)
     44                 return s1 - s2;
     45             s1 = o1.x - o1.y;
     46             s2 = o2.x - o2.y;
     47             return s1 - s2;
     48         }
     49     }
     50 
     51     static class DiffThenSumComparator implements Comparator<Obstacle> {
     52         static final DiffThenSumComparator INSTANCE = new DiffThenSumComparator();
     53 
     54         public int compare(Obstacle o1, Obstacle o2) {
     55             int s1 = o1.x - o1.y;
     56             int s2 = o2.x - o2.y;
     57             if (s1 != s2)
     58                 return s1 - s2;
     59             s1 = o1.x + o1.y;
     60             s2 = o2.x + o2.y;
     61             return s1 - s2;
     62         }
     63     }
     64 
     65     static class Obstacles {
     66         Obstacle[] bySum;
     67         Obstacle[] byDiff;
     68         int maxx;
     69         int maxy;
     70 
     71         public Obstacles(Obstacle[] ob, int maxx, int maxy) {
     72             this.maxx = maxx;
     73             this.maxy = maxy;
     74             bySum = ob.clone();
     75             Arrays.sort(bySum, SumThenDiffComparator.INSTANCE);
     76             byDiff = ob.clone();
     77             Arrays.sort(byDiff, DiffThenSumComparator.INSTANCE);
     78         }
     79 
     80         public boolean haveObstacle(int x, int y) {
     81             if (x <= 0 || x > maxx || y <= 0 || y > maxy) return true;
     82             Obstacle cur = new Obstacle();
     83             cur.x = x;
     84             cur.y = y;
     85             return Arrays.binarySearch(bySum, cur, SumThenDiffComparator.INSTANCE) >= 0;
     86         }
     87 
     88         public Obstacle getNext(int x, int y, int dx, int dy) {
     89             Obstacle cur = new Obstacle();
     90             cur.x = x;
     91             cur.y = y;
     92             if (dx == dy) {
     93                 int pos = Arrays.binarySearch(byDiff, cur, DiffThenSumComparator.INSTANCE);
     94                 if (pos >= 0) throw new RuntimeException();
     95                 pos = -(pos + 1);
     96                 if (dx > 0) {
     97                     if (pos < byDiff.length && x - y == byDiff[pos].x - byDiff[pos].y)
     98                         return byDiff[pos];
     99                     else
    100                         return getBoundary(x, y, dx, dy);
    101                 } else {
    102                     --pos;
    103                     if (pos >= 0 && x - y == byDiff[pos].x - byDiff[pos].y)
    104                         return byDiff[pos];
    105                     else
    106                         return getBoundary(x, y, dx, dy);
    107                 }
    108             } else {
    109                 int pos = Arrays.binarySearch(bySum, cur, SumThenDiffComparator.INSTANCE);
    110                 if (pos >= 0) {
    111                     throw new RuntimeException();
    112                 }
    113                 pos = -(pos + 1);
    114                 if (dx > 0) {
    115                     if (pos < bySum.length && x + y == bySum[pos].x + bySum[pos].y)
    116                         return bySum[pos];
    117                     else
    118                         return getBoundary(x, y, dx, dy);
    119                 } else {
    120                     --pos;
    121                     if (pos >= 0 && x + y == bySum[pos].x + bySum[pos].y)
    122                         return bySum[pos];
    123                     else
    124                         return getBoundary(x, y, dx, dy);
    125                 }
    126             }
    127         }
    128 
    129         private Obstacle getBoundary(int x, int y, int dx, int dy) {
    130             int times = Integer.MAX_VALUE;
    131             if (dx > 0) times = Math.min(times, maxx + 1 - x); else times = Math.min(times, x);
    132             if (dy > 0) times = Math.min(times, maxy + 1 - y); else times = Math.min(times, y);
    133             Obstacle res = new Obstacle();
    134             res.x = x + times * dx;
    135             res.y = y + times * dy;
    136             return res;
    137         }
    138     }
    139 
    140     Obstacles obstacles;
    141     int xs;
    142     int ys;
    143     int dx;
    144     int dy;
    145     List<Segment> segments = new ArrayList<Segment>();
    146 
    147     static class Segment implements Comparable<Segment> {
    148         int x1;
    149         int y1;
    150         int x2;
    151         int y2;
    152 
    153         Segment(int x1, int y1, int x2, int y2) {
    154             if (x1 < x2) {
    155                 this.x1 = x1;
    156                 this.y1 = y1;
    157                 this.x2 = x2;
    158                 this.y2 = y2;
    159             } else {
    160                 this.x1 = x2;
    161                 this.y1 = y2;
    162                 this.x2 = x1;
    163                 this.y2 = y1;
    164             }
    165         }
    166 
    167         public int compareTo(Segment o) {
    168             if (x1 != o.x1) return x1 - o.x1;
    169             if (y1 != o.y1) return y1 - o.y1;
    170             if (x2 != o.x2) return x2 - o.x2;
    171             return y2 - o.y2;
    172         }
    173     }
    174 
    175     public void solve(int testNumber, InputReader in, PrintWriter out) {
    176         int maxx = in.nextInt();
    177         int maxy = in.nextInt();
    178         int k = in.nextInt();
    179         Obstacle[] ob = new Obstacle[k];
    180         for (int i = 0; i < k; ++i) {
    181             ob[i] = new Obstacle();
    182             ob[i].x = in.nextInt();
    183             ob[i].y = in.nextInt();
    184         }
    185         xs = in.nextInt();
    186         ys = in.nextInt();
    187         String dir = in.next();
    188         if (dir.equals("NE")) {
    189             dx = -1;
    190             dy = 1;
    191         } else if (dir.equals("NW")) {
    192             dx = -1;
    193             dy = -1;
    194         } else if (dir.equals("SE")) {
    195             dx = 1;
    196             dy = 1;
    197         } else if (dir.equals("SW")) {
    198             dx = 1;
    199             dy = -1;
    200         } else throw new RuntimeException();
    201         long res = doit(maxx, maxy, ob);
    202         out.println(res);
    203     }
    204 
    205     private long doit(int maxx, int maxy, Obstacle[] ob) {
    206         shuffle(ob);
    207         obstacles = new Obstacles(ob, maxx, maxy);
    208         oneStep();
    209         int exs = xs;
    210         int eys = ys;
    211         int edx = dx;
    212         int edy = dy;
    213         segments.clear();
    214         do {
    215             oneStep();
    216         } while (xs != exs || ys != eys || dx != edx || dy != edy);
    217         List<Segment> plus = new ArrayList<Segment>();
    218         List<Segment> minus = new ArrayList<Segment>();
    219         for (Segment s : segments) {
    220             if (s.x1 + s.y1 == s.x2 + s.y2) {
    221                 plus.add(s);
    222             } else {
    223                 minus.add(s);
    224             }
    225         }
    226         Collections.sort(plus);
    227         Collections.sort(minus);
    228         int cnt = 0;
    229         for (int i = 0; i < plus.size(); ++i) {
    230             if (i == 0 || plus.get(i).compareTo(plus.get(i - 1)) > 0)
    231                 plus.set(cnt++, plus.get(i));
    232         }
    233         while (plus.size() > cnt) plus.remove(plus.size() - 1);
    234         cnt = 0;
    235         for (int i = 0; i < minus.size(); ++i) {
    236             if (i == 0 || minus.get(i).compareTo(minus.get(i - 1)) > 0)
    237                 minus.set(cnt++, minus.get(i));
    238         }
    239         while (minus.size() > cnt) minus.remove(minus.size() - 1);
    240         long res = 0;
    241         for (Segment x : plus) {
    242             res += Math.abs(x.x1 - x.x2) + 1;
    243         }
    244         for (Segment x : minus) {
    245             res += Math.abs(x.x1 - x.x2) + 1;
    246         }
    247         return res;
    248     }
    249 
    250     private void oneStep() {
    251         Obstacle meet = obstacles.getNext(xs, ys, dx, dy);
    252         int px = meet.x - dx;
    253         int py = meet.y - dy;
    254         segments.add(new Segment(xs, ys, px, py));
    255         boolean haveX = obstacles.haveObstacle(px, meet.y);
    256         boolean haveY = obstacles.haveObstacle(meet.x, py);
    257         if (haveX && !haveY) {
    258             xs = meet.x;
    259             ys = py;
    260             dy = -dy;
    261         } else if (haveY && !haveX) {
    262             xs = px;
    263             ys = meet.y;
    264             dx = -dx;
    265         } else {
    266             xs = px;
    267             ys = py;
    268             dx = -dx;
    269             dy = -dy;
    270         }
    271     }
    272 
    273     Random random = new Random(System.currentTimeMillis() + 438467315);
    274 
    275     private void shuffle(Obstacle[] x) {
    276         for (int i = 0; i < x.length; ++i) {
    277             int j = i + random.nextInt(x.length - i);
    278             Obstacle tmp = x[i];
    279             x[i] = x[j];
    280             x[j] = tmp;
    281         }
    282     }
    283 }
    284 
    285 class InputReader {
    286     public BufferedReader reader;
    287     public StringTokenizer tokenizer;
    288 
    289     public InputReader(InputStream stream) {
    290         reader = new BufferedReader(new InputStreamReader(stream));
    291         tokenizer = null;
    292     }
    293 
    294     public String next() {
    295         while (tokenizer == null || !tokenizer.hasMoreTokens()) {
    296             try {
    297                 tokenizer = new StringTokenizer(reader.readLine());
    298             } catch (IOException e) {
    299                 throw new RuntimeException(e);
    300             }
    301         }
    302         return tokenizer.nextToken();
    303     }
    304 
    305     public int nextInt() {
    306         return Integer.parseInt(next());
    307     }
    308 
    309     }
  • 相关阅读:
    eclipse下配置Spring环境
    筑梦路上的孤独行者
    Js继承各模式总结
    水题-poj1979
    C++静态数据成员存在的意义
    Mac_Sublime_JavaScript
    LeetCode204——count primes
    (吐槽)讨厌的VIP机制
    LeetCode55——Jump Game
    LeetCode62——Unique Paths
  • 原文地址:https://www.cnblogs.com/huangfeihome/p/3114304.html
Copyright © 2011-2022 走看看