結果
問題 | No.202 1円玉投げ |
ユーザー | Kilisame |
提出日時 | 2016-06-10 16:13:43 |
言語 | Java21 (openjdk 21) |
結果 |
AC
|
実行時間 | 999 ms / 5,000 ms |
コード長 | 6,709 bytes |
コンパイル時間 | 2,313 ms |
コンパイル使用メモリ | 78,652 KB |
実行使用メモリ | 75,872 KB |
最終ジャッジ日時 | 2024-06-01 20:52:15 |
合計ジャッジ時間 | 25,257 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 926 ms
75,500 KB |
testcase_01 | AC | 957 ms
74,252 KB |
testcase_02 | AC | 109 ms
52,828 KB |
testcase_03 | AC | 123 ms
53,868 KB |
testcase_04 | AC | 121 ms
54,160 KB |
testcase_05 | AC | 285 ms
59,284 KB |
testcase_06 | AC | 840 ms
70,228 KB |
testcase_07 | AC | 902 ms
70,976 KB |
testcase_08 | AC | 926 ms
70,636 KB |
testcase_09 | AC | 660 ms
64,476 KB |
testcase_10 | AC | 490 ms
62,016 KB |
testcase_11 | AC | 652 ms
63,736 KB |
testcase_12 | AC | 563 ms
64,264 KB |
testcase_13 | AC | 499 ms
61,980 KB |
testcase_14 | AC | 308 ms
59,592 KB |
testcase_15 | AC | 686 ms
64,712 KB |
testcase_16 | AC | 880 ms
75,604 KB |
testcase_17 | AC | 883 ms
75,392 KB |
testcase_18 | AC | 905 ms
75,572 KB |
testcase_19 | AC | 648 ms
63,456 KB |
testcase_20 | AC | 815 ms
67,336 KB |
testcase_21 | AC | 687 ms
64,424 KB |
testcase_22 | AC | 197 ms
57,492 KB |
testcase_23 | AC | 200 ms
57,208 KB |
testcase_24 | AC | 200 ms
57,576 KB |
testcase_25 | AC | 194 ms
57,436 KB |
testcase_26 | AC | 201 ms
57,992 KB |
testcase_27 | AC | 201 ms
57,828 KB |
testcase_28 | AC | 190 ms
57,000 KB |
testcase_29 | AC | 198 ms
58,008 KB |
testcase_30 | AC | 201 ms
57,308 KB |
testcase_31 | AC | 198 ms
58,188 KB |
testcase_32 | AC | 200 ms
56,932 KB |
testcase_33 | AC | 204 ms
58,200 KB |
testcase_34 | AC | 208 ms
56,712 KB |
testcase_35 | AC | 999 ms
75,524 KB |
testcase_36 | AC | 969 ms
75,616 KB |
testcase_37 | AC | 965 ms
74,116 KB |
testcase_38 | AC | 934 ms
75,872 KB |
testcase_39 | AC | 166 ms
54,144 KB |
testcase_40 | AC | 171 ms
54,152 KB |
ソースコード
import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Scanner; import java.util.Set; public class Main { private static final int BLOCK_SIZE = 200; private static Set<Point>[][] leftOfCoinSet = new Set[20000 / BLOCK_SIZE + 1][20000 / BLOCK_SIZE + 1]; public static void main(String[] args) { Scanner cin = new Scanner(System.in); int limit = cin.nextInt(); int leftCount = 0; for (int i = 0; i < limit; i++) { int x = cin.nextInt(); int y = cin.nextInt(); /* x,yそれぞれ1/200して、200*200の範囲内で干渉しあう円の中心情報を得る */ if (isLeft(x, y)) { leftCount++; } } System.out.println(leftCount); } private static boolean isLeft(int x, int y) { Point thisCoin = new Point(x, y); /* 落ちたコインの中心座標からブロックを求める */ int blockX = x / BLOCK_SIZE; int blockY = y / BLOCK_SIZE; /* どのブロックにまたがっているか。順に左、右、下、上、左下、右下、左上、右上で8要素配列 */ boolean[] isStradding = new boolean[4]; List<Set<Point>> checkPointList = new ArrayList<Set<Point>>(); if (leftOfCoinSet[blockX][blockY] == null) { leftOfCoinSet[blockX][blockY] = new HashSet<Point>(); } checkPointList.add(leftOfCoinSet[blockX][blockY]); if (blockX > 0 && x % BLOCK_SIZE < 10) { /* 左チェック。左端以外のBlockでかつ、x座標をBLOCK_SIZEで割った時の余りが半径の10に満たない場合 */ isStradding[0] = true; if (leftOfCoinSet[blockX - 1][blockY] == null) { leftOfCoinSet[blockX - 1][blockY] = new HashSet<Point>(); } checkPointList.add(leftOfCoinSet[blockX - 1][blockY]); } else if (blockX < 20000 / BLOCK_SIZE && x % BLOCK_SIZE >= BLOCK_SIZE - 10) { /* 右チェック。右端以外のBlockでかつ、x座標をBLOCK_SIZEで割った時の余りがBLOCK_SIZEから半径の10を引いた値以上になる場合 */ isStradding[1] = true; if (leftOfCoinSet[blockX + 1][blockY] == null) { leftOfCoinSet[blockX + 1][blockY] = new HashSet<Point>(); } checkPointList.add(leftOfCoinSet[blockX + 1][blockY]); } if (blockY > 0 && y % BLOCK_SIZE < 10) { /* 下チェック。下端以外のBlockでかつ、y座標をBLOCK_SIZEで割った時の余りが半径の10に満たない場合 */ isStradding[2] = true; if (leftOfCoinSet[blockX][blockY - 1] == null) { leftOfCoinSet[blockX][blockY - 1] = new HashSet<Point>(); } checkPointList.add(leftOfCoinSet[blockX][blockY - 1]); } else if (blockY < 20000 / BLOCK_SIZE && y % BLOCK_SIZE >= BLOCK_SIZE - 10) { /* 右チェック。右端以外のBlockでかつ、x座標をBLOCK_SIZEで割った時の余りがBLOCK_SIZEから半径の10を引いた値以上になる場合 */ isStradding[3] = true; if (leftOfCoinSet[blockX][blockY + 1] == null) { leftOfCoinSet[blockX][blockY + 1] = new HashSet<Point>(); } checkPointList.add(leftOfCoinSet[blockX][blockY + 1]); } if (isStradding[0] && isStradding[2]) { /* 左と下両方にはみ出ている場合のみ、追加で左下ブロックを判定 */ if (thisCoin.getDistance(blockX * BLOCK_SIZE - 1, blockY * BLOCK_SIZE - 1) < 100) { if (leftOfCoinSet[blockX - 1][blockY - 1] == null) { leftOfCoinSet[blockX - 1][blockY - 1] = new HashSet<Point>(); } checkPointList.add(leftOfCoinSet[blockX - 1][blockY - 1]); } } else if (isStradding[0] && isStradding[3]) { /* 左と上両方にはみ出ている場合のみ、追加で左上ブロックを判定 */ if (thisCoin.getDistance(blockX * BLOCK_SIZE - 1, (blockY + 1) * BLOCK_SIZE) < 100) { if (leftOfCoinSet[blockX - 1][blockY + 1] == null) { leftOfCoinSet[blockX - 1][blockY + 1] = new HashSet<Point>(); } checkPointList.add(leftOfCoinSet[blockX - 1][blockY + 1]); } } else if (isStradding[1] && isStradding[2]) { /* 右と下両方にはみ出ている場合のみ、追加で右下ブロックを判定 */ if (thisCoin.getDistance((blockX + 1) * BLOCK_SIZE, blockY * BLOCK_SIZE - 1) < 100) { if (leftOfCoinSet[blockX + 1][blockY - 1] == null) { leftOfCoinSet[blockX + 1][blockY - 1] = new HashSet<Point>(); } checkPointList.add(leftOfCoinSet[blockX + 1][blockY - 1]); } } else if (isStradding[1] && isStradding[3]) { /* 右と上両方にはみ出ている場合のみ、追加で右上ブロックを判定 */ if (thisCoin.getDistance((blockX + 1) * BLOCK_SIZE, (blockY + 1) * BLOCK_SIZE) < 100) { if (leftOfCoinSet[blockX + 1][blockY + 1] == null) { leftOfCoinSet[blockX + 1][blockY + 1] = new HashSet<Point>(); } checkPointList.add(leftOfCoinSet[blockX + 1][blockY + 1]); } } return checkDistance(thisCoin, checkPointList); } private static boolean checkDistance(Point point, List<Set<Point>> leftCoinSetList) { for (Set<Point> leftCoinSet : leftCoinSetList) { for (Point leftPoint : leftCoinSet) { if (leftPoint.getDistance(point) < 400) { return false; } } } for (Set<Point> leftCoinSet : leftCoinSetList) { leftCoinSet.add(point); } /* 全てチェックOKならば、チェックした対象のSetに対して自分自身を追加する */ return true; } static class Point { int x; int y; Point(int x, int y) { this.x = x; this.y = y; } public boolean equals(Point other) { return x == other.x && y == other.y; } public int getDistance(int otherX, int otherY) { return (x - otherX) * (x - otherX) + (y - otherY) * (y - otherY); } public int getDistance(Point other) { return (x - other.x) * (x - other.x) + (y - other.y) * (y - other.y); } } }