0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ARC164回答メモ

Last updated at Posted at 2023-09-18

0.はじめに
 ARC久々だなーと思い調べたら、前回は7/9なので、2か月ぶりでした。
 その時はQIITA記事書けない位の惨敗でした。
 今回も、Aすら解ける気はしなかったのですが、あがいているうちに
 なんとかAだけは解け、Bも時間は足りませんでしたが
 解き方を模索できるくらいは問題を理解できました。
 結果として、レート+17と昨日と合わせて今週だけで+34も
 あがりました。

1.A - Sum equals LCM
 初見でレーティング参加を後悔しましたが、試行錯誤の上
 なんとか解いていけました。

 【考え方1】
   N=6の例をみて、最小公倍数が6になる
   かつ、合計が6以下となる、2個以上の数列は2と3であるが
   そこに1を足している・・・
   →合計の条件を満たすために、1はいくらでも追加できる。
    →最小公倍数をみたすリストの合計がNを超えなければ
     そこに1を追加していけば条件を満たす
     →最小公倍数をみたすリストの合計がNを超えないためには
      Nが素数でなければよい、
     (素数だと、リストは2個以上の値が必要なため、
      1とNが最小公倍数リスト候補となり足すとNを超えてしまう。)
   ★Nが素数でなければなんとかなる!
   →実装した結果WA

  【考え方2】
    N=4の例を見て、素数でもなんとかならないことを悟る
   ★Nが5以下は条件を満たさない!
   →実装した結果WA

  【考え方3】
    N=9の時を考えると、素数ではないが、リスト候補には、3しか上らず
   3が2つあっても最小公倍数は3のため、条件を満たさない
   ★Nが素数で2回割れたらだめ!
   →実装した結果WA

  【考え方4】
    N=27の時を考えると、素数ではないが、リスト候補には、3しか上らず
   3が3つあっても最小公倍数は3のため、条件を満たさない
   ★Nが素数で2回以上割れたらだめ!
   →実装した結果WA

  【考え方5】
    N=72の時を考えると、素数で2回以上割れるが、A=9,8,1を55個
    と、条件を満たせる。
   ★Nが素数のべき乗だったらだめ!
   →実装した結果AC

  と、トライアンドエラーを繰り返して正解にたどり着きました。

  【実装】
    [素数リスト作成]
     実装は、1つ1つ素数で割っていったらまにあわなそうだったので
     まず素数のリストを作ろうと思い、ぐぐったら、エラトステネスの篩で
     素数を求める例があったのでこぴって使いました。
     素数リストの上限は、Nの最大値の0.5乗≒31623までとし
     最初に素数リストLを作成。
    [条件を満たさないかの判定関数 is_prime、条件を満たさない時Trueを返す]
     ※考え方の最初、素数だったらだめ!というときに作った関数なので
      素数判定のような関数名になっている
     1)変数chkに0をセット
      (chk:n以外で素数で割切れるかつ、素数のべき乗でない場合1をセット)
     2)for文でリストLの要素をxに入れて一つずつチェック
      2-1)nがxで割り切れる場合
      2-1-1)chkNにnをxで割った値をセット
      2-1-2)変数flgに0をセット
      2-1-3)flgが0の間以下を繰り返す
        2-1-3-1)chkNがxで割り切れる場合
          2-1-3-1-1)chkNにchkNをxで割った値をセット
            2-1-3-1-1-1)chkNがxで割り切れない場合flgに1をセット
        2-1-3-2)chkNがxで割り切れない場合はflgに1をセット
         ↑ここら辺はループしているのに次のループでするべき判定を
          先取りしていて冗長なのでごちゃっとしている
      2-1-4)chkNが1の時、nはxのべき乗であるためTrue(条件を満たさない)を返す
      2-1-5)chkNが1でない時、chkに1をセット
      2-2)nがxで割り切れない場合は次のxへ
     3)chkが0の場合、Trueを1の場合Falseを返す
    [メイン処理部分]
     1)Tを読み込む
     2)以下T回繰り返し
      2-1)Nを読み込む
      2-2)Nが5以下の時Noを出力
      2-3)Nが6以上の場合
        2-3-1)is_prime(N)の戻り値がTrueの場合Noを出力
        2-3-1)is_prime(N)の戻り値がFalseの場合Yesを出力
 忘れないようにまとめましたが無駄に長くなったし
 内容も書き直したくなるくらい無駄が多いなと思います・・・。

 https://atcoder.jp/contests/arc165/submissions/45679114

2.B - Sliding Window Sort 2
 コンテスト中はなんとなく直感でこうすればよさそうというのは
 思い浮かんだのですが、実装まで落とし込めませんでした。
 まぁ、解説を読んでもパット理解できなかったので、直感も
 あってたかはわかりませんが・・・。
 解説を読んで理解した考え方を忘れないよう自分の言葉でメモ。

 【考え方】
  1)操作をすることによって、辞書順が大きくなることは無い。
    最大でも、元のリストと同じ状態。
    →操作しても辞書順が変わらないケースは
     リストの値が、K個昇順に並んでいる場合なので
     そのような並びがあった場合は、リストをそのまま出力して終了
  2)辞書順を大きくするためには、なるべく元のリストの儘が良い。
   変える場合も、先頭の方は変えない方がよいので
   リストのうしろから、K個をソートしたリストを回答候補1として保持
  3)回答候補1と元のリストを先頭から比較して、一番最初に
   差異が出た位置をiとしたとき、iの前の部分が昇順に並んでいたら
   その並び順を活かす方が変化が少ないため、iを含むK個の列の値のうち
   iより前の部分の昇順な並びが最大になるような位置からK個を
   ソートした値を回答候補2として保持
  4)回答候補1と回答候補2のうち、辞書順で大きい方を出力して終了

 一応メモとして残しましたが、解説放送を見た方が、理解しやすいかと思いました。

 https://atcoder.jp/contests/arc165/submissions/45688012

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?