Submission #68094224


Source Code Expand

import sys
import time
import tracemalloc
from typing import Tuple, List, NamedTuple, Optional, Callable, Any, TypeVar
from dataclasses import dataclass

# 型変数の定義
T = TypeVar('T')
P = TypeVar('P')


@dataclass(frozen=True)
class PerformanceMetrics:
    """パフォーマンス測定結果を格納するデータクラス"""
    execution_time_ms: float
    memory_used_mb: float
    peak_memory_mb: float


class Card(NamedTuple):
    """カード情報を表すNamedTuple(メモリ効率最適化)"""
    a: int
    b: int


def solve_card_score_optimized(input_str: str) -> int:
    """
    カードスコア最大化問題を解く関数(最適化版)
    
    アルゴリズム:
    スコア = |表の総和| + |裏の総和| を最大化
    4つのパターンを同時計算:
    1. 表≥0, 裏≥0: スコア = 表の総和 + 裏の総和
    2. 表≥0, 裏<0: スコア = 表の総和 - 裏の総和  
    3. 表<0, 裏≥0: スコア = -表の総和 + 裏の総和
    4. 表<0, 裏<0: スコア = -表の総和 - 裏の総和
    
    Args:
        input_str (str): 標準入力の文字列
        
    Returns:
        int: 最大スコア
        
    Time Complexity: O(N)
    Space Complexity: O(1)
    """
    lines: List[str] = input_str.strip().split('\n')
    n: int = int(lines[0])
    
    # 4つのパターンのスコアを同時に計算(型ヒント付き)
    score1: int = 0  # パターン1: a + b (両方非負)
    score2: int = 0  # パターン2: a - b (表非負、裏負)
    score3: int = 0  # パターン3: -a + b (表負、裏非負)
    score4: int = 0  # パターン4: -a - b (両方負)
    
    # 各カードを1回だけ読み込んで処理(メモリ効率最大化)
    for i in range(1, n + 1):
        # split()の結果を直接アンパック(中間リスト削除)
        a_str, b_str = lines[i].split()
        a: int = int(a_str)
        b: int = int(b_str)
        
        # 各パターンでの貢献度を計算(インライン計算)
        contrib1: int = a + b
        contrib2: int = a - b
        contrib3: int = -a + b
        contrib4: int = -a - b
        
        # 条件分岐で効率的に加算(Python 3.11の最適化活用)
        if contrib1 > 0:
            score1 += contrib1
        if contrib2 > 0:
            score2 += contrib2
        if contrib3 > 0:
            score3 += contrib3
        if contrib4 > 0:
            score4 += contrib4
    
    # max()関数を使わず条件分岐で最大値を効率的に求める
    max_score: int = score1
    if score2 > max_score:
        max_score = score2
    if score3 > max_score:
        max_score = score3
    if score4 > max_score:
        max_score = score4
    
    return max_score


def solve(input_str: str) -> str:
    """
    標準入力から問題を読み込み、解答を出力する関数
    
    Args:
        input_str (str): 標準入力の文字列
        
    Returns:
        str: 解答文字列
    """
    return str(solve_card_score_optimized(input_str))


def measure_performance(func: Callable[..., T], *args: Any) -> Tuple[T, PerformanceMetrics]:
    """
    関数のパフォーマンスを測定する関数
    
    Args:
        func (Callable[..., T]): 測定対象の関数
        *args (Any): 関数の引数
        
    Returns:
        Tuple[T, PerformanceMetrics]: 実行結果とパフォーマンス指標
    """
    # メモリトレースを開始
    tracemalloc.start()
    
    # 実行時間測定開始
    start_time: float = time.perf_counter()
    
    # 関数実行
    result: T = func(*args)
    
    # 実行時間測定終了
    end_time: float = time.perf_counter()
    
    # メモリ使用量取得
    current_memory: int
    peak_memory: int
    current_memory, peak_memory = tracemalloc.get_traced_memory()
    tracemalloc.stop()
    
    # パフォーマンス指標計算
    execution_time_ms: float = (end_time - start_time) * 1000
    memory_used_mb: float = current_memory / 1024 / 1024
    peak_memory_mb: float = peak_memory / 1024 / 1024
    
    metrics: PerformanceMetrics = PerformanceMetrics(
        execution_time_ms=execution_time_ms,
        memory_used_mb=memory_used_mb,
        peak_memory_mb=peak_memory_mb
    )
    
    return result, metrics


def generate_large_test_case(n: int) -> str:
    """
    大きなテストケースを生成する関数
    
    Args:
        n (int): カードの枚数
        
    Returns:
        str: テスト用入力文字列
    """
    import random
    
    lines: List[str] = [str(n)]
    
    # シード固定で再現可能なテスト
    random.seed(42)
    
    for _ in range(n):
        # -10^9 to 10^9 の範囲でランダム生成
        a: int = random.randint(-1_000_000_000, 1_000_000_000)
        b: int = random.randint(-1_000_000_000, 1_000_000_000)
        lines.append(f"{a} {b}")
    
    return '\n'.join(lines)


def validate_input(input_str: str) -> bool:
    """
    型安全な入力検証関数
    
    Args:
        input_str (str): 検証対象の入力
        
    Returns:
        bool: 入力が有効かどうか
    """
    try:
        lines: List[str] = input_str.strip().split('\n')
        
        if len(lines) < 1:
            return False
        
        n: int = int(lines[0])
        if n < 1 or n > 100_000:
            return False
        
        if len(lines) != n + 1:
            return False
        
        for i in range(1, n + 1):
            parts: List[str] = lines[i].split()
            if len(parts) != 2:
                return False
            
            a: int = int(parts[0])
            b: int = int(parts[1])
            
            if abs(a) > 1_000_000_000 or abs(b) > 1_000_000_000:
                return False
        
        return True
        
    except (ValueError, IndexError):
        return False


def run_tests() -> None:
    """テスト実行関数"""
    print("=== Python版 カードスコア最大化問題 テスト ===\n")
    
    # 基本テストケース
    test_input: str = """5
2 8
4 -5
5 -3
-4 1
-2 -3"""
    
    print("基本テストケース:")
    result: str
    metrics: PerformanceMetrics
    result, metrics = measure_performance(solve, test_input)
    print(f"結果: {result} (期待値: 18)")
    print(f"実行時間: {metrics.execution_time_ms:.3f} ms")
    print(f"メモリ使用量: {metrics.memory_used_mb:.3f} MB")
    print(f"ピークメモリ: {metrics.peak_memory_mb:.3f} MB\n")
    
    # パフォーマンステスト
    sizes: Tuple[int, ...] = (1_000, 10_000, 50_000, 100_000)
    
    for size in sizes:
        print(f"パフォーマンステスト (N={size:,}):")
        large_input: str = generate_large_test_case(size)
        perf_result: str
        perf_metrics: PerformanceMetrics
        perf_result, perf_metrics = measure_performance(solve, large_input)
        
        print(f"結果: {perf_result}")
        print(f"実行時間: {perf_metrics.execution_time_ms:.3f} ms")
        print(f"メモリ使用量: {perf_metrics.memory_used_mb:.3f} MB")
        print(f"ピークメモリ: {perf_metrics.peak_memory_mb:.3f} MB")
        print(f"1カードあたりの処理時間: {perf_metrics.execution_time_ms / size * 1000:.3f} μs\n")


def main() -> None:
    """メイン処理関数"""
    try:
        # 標準入力から一度に全て読み込み
        input_str: str = sys.stdin.read()
        
        # 入力検証(デバッグ時のみ有効化)
        # if not validate_input(input_str):
        #     print("Invalid input format", file=sys.stderr)
        #     sys.exit(1)
        
        result: str = solve(input_str)
        print(result)
        
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    # テストを実行したい場合はコメントアウト
    # run_tests()
    
    # 本番実行
    main()

Submission Info

Submission Time
Task B42 - Two Faced Cards
User myoshizumi
Language Python (CPython 3.11.4)
Score 1000
Code Size 8262 Byte
Status AC
Exec Time 92 ms
Memory 25448 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 1000 / 1000
Status
AC × 1
AC × 12
Set Name Test Cases
Sample sample_01.txt
All hand_01.txt, hand_02.txt, random_large_00.txt, random_large_01.txt, random_large_02.txt, random_small_00.txt, random_small_01.txt, random_small_02.txt, random_small_03.txt, random_small_04.txt, sample_01.txt, test_01.txt
Case Name Status Exec Time Memory
hand_01.txt AC 30 ms 12760 KiB
hand_02.txt AC 30 ms 12744 KiB
random_large_00.txt AC 91 ms 25376 KiB
random_large_01.txt AC 92 ms 25448 KiB
random_large_02.txt AC 92 ms 25400 KiB
random_small_00.txt AC 30 ms 12620 KiB
random_small_01.txt AC 30 ms 12712 KiB
random_small_02.txt AC 30 ms 12756 KiB
random_small_03.txt AC 32 ms 12700 KiB
random_small_04.txt AC 29 ms 12720 KiB
sample_01.txt AC 30 ms 12808 KiB
test_01.txt AC 68 ms 20628 KiB