くろたんく雑記帳

日常とか、わんちゃんとか、機械学習とか、競プロとか、

MENU

Python3で解く エイシング プログラミング コンテスト 2020 C - XYZ Triplets

Cにしては簡単な全探索だった。なのに変なやり方でやってしまった・・・

概要

問題

  • {\displaystyle f(n)}は以下を満たす{\displaystyle x, y, z}の組の数である。
  • {\displaystyle 1 \leqq x, y, z}
  • {\displaystyle x^2 + y^2 + z^2 + x \times y + y \times z + z \times x = n}
  • 整数nを与えるのでf(1), f(2) ... f(n)を出力できる?
制約
  • 与えられるものは全て整数
  • {\displaystyle 1 \leqq n \leqq 10^4}

解くときに考えた内容

  • {\displaystyle 1 \leqq n \leqq 10^4}{\displaystyle 1 \leqq x, y, z}から考えると{\displaystyle 1 \leqq x, y, z \leqq 100}全てで第2式を計算してリストに加える。
    1. 実装的にはproductで3つの1~100までの全パータンを列挙する。
    2. 列挙したものを式に代入する。
    3. これによってざっと制約の範囲の{\displaystyle f(n)}が計算される。
  • Counterで計算された{\displaystyle n}ごとにカウントする。
  • あとは存在しないものは0としてあるものはカウントの値を出力。
    • Counter.get(i)で存在しないものはNoneでよい(というのも今回知った)
  • productで3つの1~100までの全パータンを列挙しなくてもforを3層にすればよかったね・・・ ここら辺の出力の仕方は、出力のところでまとめてある。 blacktanktop.hatenablog.com

コード

変なやり方でやってしまった・・・
from itertools import product 
from collections import Counter

N = int(input())
# 全パターン列挙
pattern = list(product(list(range(1, 100)),repeat=3))
l = list()
for i in pattern:
    x, y, z = i
    n = x**2 + y**2 + z**2 + x*y + y*z + z*x
    l.append(n)
# nの数を全部数える
ans = Counter(l)
for i in range(1, N+1):
    # 無いなら出力は0
    if ans.get(i) == None:
        print(0)
    else:
        print(ans.get(i))
素直にやればこうだった。
N = int(input())
# 0を含んでNまでのリストを作る
ans = [0] * (N+1)
# 制約から100まで調べればいい
for x in range(1,101):
    for y in range(1,101):
        for z in range(1,101):
            n = x**2 + y**2 + z**2 + x*y + y*z + z*x
            # 計算値がN以下の時だけindexがnに1を足し続けてカウント
            if n <= N:
                ans[n] += 1
# 最後はindexが0以外をアンパックして改行して出力
print(*ans[1:], sep='\n')