結果
問題 | No.376 立方体のN等分 (2) |
ユーザー | Kilisame |
提出日時 | 2016-06-07 14:51:46 |
言語 | Java21 (openjdk 21) |
結果 |
AC
|
実行時間 | 607 ms / 5,000 ms |
コード長 | 5,396 bytes |
コンパイル時間 | 2,479 ms |
コンパイル使用メモリ | 82,088 KB |
実行使用メモリ | 44,800 KB |
最終ジャッジ日時 | 2024-11-06 23:27:57 |
合計ジャッジ時間 | 12,064 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 153 ms
42,264 KB |
testcase_01 | AC | 156 ms
42,260 KB |
testcase_02 | AC | 240 ms
42,220 KB |
testcase_03 | AC | 243 ms
42,832 KB |
testcase_04 | AC | 607 ms
42,684 KB |
testcase_05 | AC | 160 ms
42,148 KB |
testcase_06 | AC | 155 ms
42,288 KB |
testcase_07 | AC | 155 ms
42,380 KB |
testcase_08 | AC | 159 ms
42,532 KB |
testcase_09 | AC | 184 ms
42,564 KB |
testcase_10 | AC | 277 ms
44,800 KB |
testcase_11 | AC | 158 ms
42,352 KB |
testcase_12 | AC | 242 ms
42,348 KB |
testcase_13 | AC | 226 ms
42,460 KB |
testcase_14 | AC | 156 ms
42,368 KB |
testcase_15 | AC | 158 ms
42,448 KB |
testcase_16 | AC | 212 ms
43,388 KB |
testcase_17 | AC | 208 ms
42,528 KB |
testcase_18 | AC | 161 ms
42,796 KB |
testcase_19 | AC | 244 ms
42,604 KB |
testcase_20 | AC | 160 ms
42,468 KB |
testcase_21 | AC | 230 ms
43,356 KB |
testcase_22 | AC | 165 ms
42,352 KB |
testcase_23 | AC | 230 ms
43,272 KB |
testcase_24 | AC | 237 ms
43,368 KB |
testcase_25 | AC | 164 ms
42,280 KB |
testcase_26 | AC | 256 ms
43,856 KB |
testcase_27 | AC | 150 ms
41,828 KB |
testcase_28 | AC | 155 ms
42,552 KB |
testcase_29 | AC | 170 ms
42,384 KB |
testcase_30 | AC | 157 ms
42,464 KB |
testcase_31 | AC | 277 ms
42,404 KB |
testcase_32 | AC | 157 ms
42,260 KB |
testcase_33 | AC | 275 ms
42,388 KB |
testcase_34 | AC | 277 ms
42,336 KB |
testcase_35 | AC | 159 ms
42,236 KB |
testcase_36 | AC | 147 ms
41,880 KB |
testcase_37 | AC | 158 ms
42,528 KB |
testcase_38 | AC | 159 ms
42,368 KB |
testcase_39 | AC | 255 ms
42,760 KB |
ソースコード
import java.math.BigInteger; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner cin = new Scanner(System.in); String line = null; while (cin.hasNext()) { line = cin.nextLine(); } cin.close(); divided(Long.parseLong(line)); } private static void divided(long n) { long maxSlice = n - 1; long minSlice = n - 1; /* nが素数か判定する */ boolean isPrime = new BigInteger(String.valueOf(n)).isProbablePrime(15); if (isPrime) { minSlice = n - 1; } else { double thirdRoot = Math.cbrt(n); if (thirdRoot == (long) thirdRoot) { /* たまたまNが整数の3乗だった場合は、(thirdRoot-1)*3が答え */ minSlice = ((long) thirdRoot - 1) * 3; } else { /* 3乗根が整数にならないのであれば、それより小さい値から順に割っていき、3乗根以下でもっとも大きい約数を求める */ long divisorUnderThirdRoot = n; for (long i = (long) thirdRoot; i > 1; i--) { if (n % i == 0) { divisorUnderThirdRoot = i; long rest = n / divisorUnderThirdRoot; /* 割った残りの値が素数かを判定する */ boolean isPrimeOfRest = new BigInteger(String.valueOf(rest)).isProbablePrime(8); if (isPrimeOfRest) { /* 残りの数が素数なのであれば、約数側がさらに2数の積にならないかを確認する */ boolean isPrimeOfDivisor = new BigInteger(String.valueOf(divisorUnderThirdRoot)).isProbablePrime(8); if (isPrimeOfDivisor) { /* Nが素数×素数の形になってしまった場合、それ以上の分割は無理 */ minSlice = (divisorUnderThirdRoot - 1) + (rest - 1); break; } else { /* 約数側をさらに2数の積で分割する。約数の平方根をとる */ double rootOfDivisor = Math.sqrt(divisorUnderThirdRoot); if (rootOfDivisor == (long) rootOfDivisor) { /* 平方根が整数だった場合は、(root-1)*2に(rest-1)を足したものが答え */ minSlice = ((long) rootOfDivisor - 1) * 2 + (rest - 1); break; } else { long divisorOverRoot = divisorUnderThirdRoot; for (long j = (long) rootOfDivisor; j > 1; j--) { if (divisorUnderThirdRoot % j == 0) { divisorOverRoot = j; break; } } long result = divisorUnderThirdRoot / divisorOverRoot; minSlice = (rest - 1) + (divisorOverRoot - 1) + (result - 1); break; } } } else { /* 残った数が素数でないなら、そちらをさらに2数の積の形にする。 */ double rootOfRest = Math.sqrt(rest); long tempMinSlice; if (rootOfRest == (long) rootOfRest) { tempMinSlice = ((long) rootOfRest - 1) * 2 + (divisorUnderThirdRoot - 1); } else { long divisorOfRoot = rest; for (long j = (long) rootOfRest; j > 1; j--) { if (rest % j == 0) { divisorOfRoot = j; break; } } long result = rest / divisorOfRoot; tempMinSlice = (divisorOfRoot - 1) + (result - 1) + (divisorUnderThirdRoot - 1); } if (tempMinSlice < minSlice) { minSlice = tempMinSlice; } } } } if (minSlice == n - 1) { /* 素数でないのに3乗根より小さい約数がないということは、3乗根より大きい2素数の積で表せる数ということなので、平方根で考える */ double root = Math.sqrt(n); for (long i = (long) root; i > 1; i--) { if (n % i == 0) { minSlice = (i - 1) + (n / i - 1); } } } } } System.out.println(minSlice + " " + maxSlice); } }