結果
問題 | No.202 1円玉投げ |
ユーザー | Kilisame |
提出日時 | 2016-06-10 16:13:43 |
言語 | Java21 (openjdk 21) |
結果 |
AC
|
実行時間 | 1,291 ms / 5,000 ms |
コード長 | 6,709 bytes |
コンパイル時間 | 3,148 ms |
コンパイル使用メモリ | 78,548 KB |
実行使用メモリ | 69,592 KB |
最終ジャッジ日時 | 2024-12-22 10:26:49 |
合計ジャッジ時間 | 30,996 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1,127 ms
68,688 KB |
testcase_01 | AC | 1,291 ms
69,592 KB |
testcase_02 | AC | 148 ms
47,844 KB |
testcase_03 | AC | 141 ms
46,044 KB |
testcase_04 | AC | 142 ms
46,284 KB |
testcase_05 | AC | 330 ms
51,892 KB |
testcase_06 | AC | 1,146 ms
60,356 KB |
testcase_07 | AC | 1,214 ms
68,476 KB |
testcase_08 | AC | 1,176 ms
68,348 KB |
testcase_09 | AC | 853 ms
56,504 KB |
testcase_10 | AC | 581 ms
55,052 KB |
testcase_11 | AC | 774 ms
54,256 KB |
testcase_12 | AC | 763 ms
56,284 KB |
testcase_13 | AC | 611 ms
54,804 KB |
testcase_14 | AC | 335 ms
51,920 KB |
testcase_15 | AC | 841 ms
55,220 KB |
testcase_16 | AC | 1,083 ms
68,232 KB |
testcase_17 | AC | 1,090 ms
68,284 KB |
testcase_18 | AC | 1,075 ms
68,480 KB |
testcase_19 | AC | 774 ms
56,180 KB |
testcase_20 | AC | 1,081 ms
60,156 KB |
testcase_21 | AC | 829 ms
56,032 KB |
testcase_22 | AC | 225 ms
49,344 KB |
testcase_23 | AC | 235 ms
49,144 KB |
testcase_24 | AC | 233 ms
48,108 KB |
testcase_25 | AC | 234 ms
49,040 KB |
testcase_26 | AC | 229 ms
47,708 KB |
testcase_27 | AC | 240 ms
48,984 KB |
testcase_28 | AC | 234 ms
47,740 KB |
testcase_29 | AC | 227 ms
47,748 KB |
testcase_30 | AC | 238 ms
48,312 KB |
testcase_31 | AC | 231 ms
48,608 KB |
testcase_32 | AC | 233 ms
47,772 KB |
testcase_33 | AC | 234 ms
48,484 KB |
testcase_34 | AC | 230 ms
47,504 KB |
testcase_35 | AC | 1,176 ms
66,852 KB |
testcase_36 | AC | 1,225 ms
69,128 KB |
testcase_37 | AC | 1,255 ms
68,744 KB |
testcase_38 | AC | 1,157 ms
68,852 KB |
testcase_39 | AC | 186 ms
48,324 KB |
testcase_40 | AC | 192 ms
46,456 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); } } }