結果
問題 | No.180 美しいWhitespace (2) |
ユーザー | rpy3cpp |
提出日時 | 2015-05-19 18:41:52 |
言語 | Python3 (3.12.2 + numpy 1.26.4 + scipy 1.12.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 3,919 bytes |
コンパイル時間 | 73 ms |
コンパイル使用メモリ | 12,928 KB |
実行使用メモリ | 11,264 KB |
最終ジャッジ日時 | 2024-07-06 05:44:04 |
合計ジャッジ時間 | 1,915 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 30 ms
11,008 KB |
testcase_01 | AC | 29 ms
11,136 KB |
testcase_02 | AC | 27 ms
11,136 KB |
testcase_03 | WA | - |
testcase_04 | AC | 27 ms
11,136 KB |
testcase_05 | AC | 28 ms
11,136 KB |
testcase_06 | AC | 28 ms
11,136 KB |
testcase_07 | AC | 30 ms
11,136 KB |
testcase_08 | AC | 30 ms
11,136 KB |
testcase_09 | AC | 31 ms
11,136 KB |
testcase_10 | AC | 33 ms
11,136 KB |
testcase_11 | AC | 33 ms
11,136 KB |
testcase_12 | AC | 30 ms
11,264 KB |
testcase_13 | AC | 31 ms
11,136 KB |
testcase_14 | AC | 32 ms
11,136 KB |
testcase_15 | AC | 30 ms
11,136 KB |
testcase_16 | AC | 34 ms
11,136 KB |
testcase_17 | AC | 31 ms
11,136 KB |
testcase_18 | AC | 31 ms
11,136 KB |
testcase_19 | AC | 32 ms
11,136 KB |
testcase_20 | AC | 26 ms
11,264 KB |
testcase_21 | AC | 26 ms
11,136 KB |
testcase_22 | AC | 25 ms
11,008 KB |
testcase_23 | AC | 25 ms
11,136 KB |
testcase_24 | AC | 26 ms
11,136 KB |
testcase_25 | AC | 26 ms
11,136 KB |
testcase_26 | AC | 26 ms
11,136 KB |
testcase_27 | AC | 25 ms
11,008 KB |
testcase_28 | AC | 26 ms
11,008 KB |
testcase_29 | AC | 26 ms
11,136 KB |
testcase_30 | AC | 31 ms
11,136 KB |
testcase_31 | AC | 32 ms
11,136 KB |
testcase_32 | AC | 29 ms
11,136 KB |
testcase_33 | AC | 30 ms
11,136 KB |
testcase_34 | AC | 28 ms
11,264 KB |
ソースコード
def convex_hull(points): '''二次元平面上の点のリスト points の凸包を返す。Andrew のアルゴリズムを使用。 引数: points = [(x0, y0), (x1, y1),...] 点のリスト 同じ点は含まない(全て異なる点である)とする。 返り値: convex_hull = [(xi, yi), (xj, yj),...] 点のリスト。時計回りに並んでいる。 ''' points.sort() upper_bounds = get_bounds(points) points.reverse() lower_bounds = get_bounds(points) del upper_bounds[-1] del lower_bounds[-1] upper_bounds.extend(lower_bounds) return upper_bounds def get_bounds(points): bounds = [points[0], points[1]] for xi, yi in points[2:]: while len(bounds) > 1 and not is_convex(bounds, xi, yi): del bounds[-1] bounds.append((xi, yi)) return bounds def is_convex(bounds, x2, y2): x1, y1 = bounds[-1] x0, y0 = bounds[-2] return (x1 - x0) * (y2 - y1) < (y1 - y0) * (x2 - x1) def read_data(): N = int(input()) AB = [tuple(map(int, input().split())) for i in range(N)] return N, AB def solve(N, AB): # 重複する点を除く AB = list(set(AB)) if len(AB) == 1: return 1 # 凸包を得る ps = convex_hull(AB) ps.reverse() # 反時計回りに並べ直す。 # tab = 1 としたときの最小値と最大値の出現場所にカーソルをおく。 xy = [x + y for x, y in ps] min_xy = min(xy) max_xy = max(xy) min_idx = xy.index(min_xy) max_idx = xy.index(max_xy) # 凸包を半時計回りに走査して、 x + tab * y の幅が最小となる tab をさがす。 return find_best_tab_width(ps, min_idx, max_idx) def find_best_tab_width(ps, min_idx, max_idx): n = len(ps) tab = 1.0 min_cost = float('inf') while tab > 0: tab_int0 = int(tab) tab_int1 = tab_int0 + 1 new_cost0 = cost(ps, min_idx, max_idx, tab_int0, n) new_cost1 = cost(ps, min_idx, max_idx, tab_int1, n) if new_cost0 < min_cost: min_cost = new_cost0 best_tab = tab_int0 if new_cost1 < min_cost: min_cost = new_cost1 best_tab = tab_int1 min_idx, max_idx, tab = get_next(ps, n, min_idx, max_idx, tab) return best_tab def cost(ps, min_idx, max_idx, tab, n): '''計算誤差に対処するため、最小値, 最大値をとるはずのidx の前後についても計算している。 ''' min_idxs = [(min_idx-1) % n, min_idx, (min_idx+1) % n] min_val = min([ps[i][0] + tab * ps[i][1] for i in min_idxs]) max_idxs = [(max_idx-1) % n, max_idx, (max_idx+1) % n] max_val = max([ps[i][0] + tab * ps[i][1] for i in max_idxs]) return max_val - min_val def get_next(ps, n, min_idx, max_idx, tab): min_x0, min_y0 = ps[min_idx] min_x1, min_y1 = ps[(min_idx + 1) % n] max_x0, max_y0 = ps[max_idx] max_x1, max_y1 = ps[(max_idx + 1) % n] dx_min, dy_min = min_x1 - min_x0, min_y0 - min_y1 dx_max, dy_max = max_x0 - max_x1, max_y1 - max_y0 tab_min_f = get_slope(dx_min, dy_min) tab_max_f = get_slope(dx_max, dy_max) if tab_min_f == 0: return min_idx, (max_idx + 1) % n, tab_max_f if tab_max_f == 0: return (min_idx + 1) % n, max_idx, tab_min_f if tab_min_f < tab_max_f: return (min_idx + 1) % n, max_idx, tab_min_f if tab_max_f < tab_min_f: return min_idx, (max_idx + 1) % n, tab_max_f else: return (min_idx + 1) % n, (max_idx + 1) % n, tab_min_f def get_slope(dx, dy): if dx <= 0 or dy <= 0: return 0 else: return 1.0 * dx / dy def checker(tab, AB): for TAB in [tab - 1, tab, tab + 1]: xy = [x + TAB * y for x, y in AB] score = max(xy) - min(xy) print(score) if __name__ == '__main__': N, AB = read_data() print(solve(N, AB))