2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

0.はじめに

 前回茶色落ちしたものの、あと2つ上がれば緑に戻れるので
 気合を入れなおして臨んだコンテスト。
 今回はなかなか手ごたえがあり、Cでも苦戦するも
 なんとかDまで解けました。
 これは言ったかなと思いましたが、レートは+1と1足りずに
 茶色にとどまりました。
 まぁ、緑だからどうということも無いのですが、何か悔しい感じです。

1.A - Triple Four

 なんとなく、前回のAと似た問題。
 リストを3つ目の値から見ていき
 今見ている値が2つ前の値と同じ&1つ前の値と同じ場合
 Yesを出力して終了
 最後までみて終了していなければNoを出力して終了

 https://atcoder.jp/contests/abc396/submissions/63495376

2.B - Card Pile

 キューの練習のような問題。
 キューqを用意し、
 1のクエリーの時は、キューにクエリーで示された値を格納
 2のクエリーの時は、キューが空なら0を
 空でなければqの右端を取り出して出力
 
 まぁカンタンですが、B問題でキューを使うようになるとは・・・。

 https://atcoder.jp/contests/abc396/submissions/63504130

3.C - Buy Balls

 意外と難しく、諦めかけた問題。
 【考え方】
  1)黒のボール数が白以上になるという制約をなくした場合
   白と黒それぞれ何個ボールを取り出した場合に
   価値が最大になるかを求める
  2)1)で求めた黒のボール数が、白のボール数以上なら
   1)で求めた価値が回答となる
  3)1)で求めた黒のボール数が、白のボール数未満の時
   黒と白の数が同じになるまで、価値の減少が少なくなるように
   黒を減らすor白を増やすようボールを選んでいく

 【実装】
  1.変数N、M・リストB、Wを読み込む
  2.BとWを降順ソートする
  3.Bからボールを取り出す場合の価値の最大を求める
   -1.変数BS(Bの価値の合計:初期値0)、Bi(価値がBSの時のボール数-1:初期値-1)を定義
     Bから1つも取り出さない場合の方が価値が高くなる状態を初期値とする(Bの価値がすべてマイナスの場合)
   -2.リストBをインデックスiで先頭から見ていく
    -1.B[i]が0以上の時BSにB[i]を加算し、Biにiをセット
    -2.B[i]が0未満の時ブレイク
  4.3同様に、Wからボールを取り出す場合の価値の最大を求める
   変数は、WSとWi(後で考えると、Wは価値が0より大きい場合で参照すればよかったですが
   提出時はBと同じロジックで見ています)
  5.BiがWiより小さい場合以下繰り返し(Bi≧Wiの時は条件を満たしているので5の処理は行わない)
   ~黒を増やした場合の価値の減少値Bxを求める
   -1.BiがN-1より小さい場合、BxはB[Bi+1]*-1(黒の袋から最大の数(マイナス値)を取り出した場合に減少する価値)
   -2.BiがN-1と同じ場合は、黒の袋からボールは取り出せないので、BxにINF(10の18乗)をセット
   ~白を減らした場合の価値の減少値Wxを求める
   -3.Wiが0以上の時、WxにW[Wi]をセット
   -4.Wiが0の時は白の袋からボールは取り出せないので、WxにINF(10の18乗)をセット
   -5.WxよりBxが大きい場合(黒のボール数を増やした方が価値の減少が少ない場合)
    -1.Biに1を加算し、BSにB[Bi]を加算
   -6.WxがBx以上の場合(白のボール数を減らした方が価値の減少が少ない場合)
    -1.WSから、W[Wi]を減算し、Wiから1減算
  6.BS+WSを出力して終了

 https://atcoder.jp/contests/abc396/submissions/63539360

4.D - Minimum XOR Path

 DFS問題に単純な重さではなく、XORで色付けした問題といった感じ。
 根はCOBOL出身の古いプログラマーのため、再帰関数とか今一苦手なので
 不安に思いながら実装。
 【実装】
  ~前準備
  1.変数N、Mを読み込む
  2.デフォルトリスト型辞書D(キー:頂点、値:tuple(キーとつながっている頂点とその辺のラべル値))を定義
  3.リストR(DFS時に訪れた頂点を保持するリスト)を[0]×(N+1)で初期化
  4.回答保持用変数ansを2の61乗で初期化
  6.M回辺情報読み込み
   -1.u、v、wを読み込む
   -2.D[u]に(v,w)を追加
   -3.D[w]に(u,w)を追加
  6.関数dfs定義(引数 x:チェック始点の頂点、y:チェック終点の頂点、w:チェック中経路のラベルXOR合計値)
   (後で見るとyは不要だった)
   -1.グローバル変数としてansとRを定義
   -2.xがNと同じとき
    -1.ansにansとwの小さい方をセット
    -2.リターン
   -3.以下、D[x]からxx,xwを取り出し繰り返し
    -1.R[xx]が0の時(今調べている経路で通ってない時)
     -1.R[xx]に1をセット
     -2.関数dfsを引数(xx,y,w^xw)で呼び出し
     -3.R[xx]に0をセット
  ~メイン処理
  7.R[1]に1をセット
  8.関数dfsを引数(0,N,0)で呼び出し
  9.ansを出力して終了

 最初、ansの初期値を10の18乗にして提出したところ2問WAとなり
 よくよく調べたら、Wの制約である2の60乗の方が大きい事に気づき
 2の61乗に変更したところACでした。
 ここさえ気づいていれば、緑行けたかも…と悔やみました。

 https://atcoder.jp/contests/abc396/submissions/63552894

以上

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?