れとろのメモ置場

とあるSEのメモ置場

Outer Wildsを起動したらメニューが表示されなかった【バグ解決済み】

DLCも出たので久々にOuter Wildsやろうとインストールし直したらメニューが何も表示されないバグが起きた。 解決はしたけど日本語の対処方法が出てこなかったので一応メモを残しておこうと思う。

一旦投稿しておく。後で見直して修正するかも

バグ概要

前提

  • Steamからダウンロードしインストール
  • 以前一通りクリアしてその後削除。今回再度インストールを実施。
    以前のデータはSteam側で保存済み

    バグの内容

    2021/10/01にSteamでOuter Wildsをインストール後起動したらメニューが何も表示されなかった。

対応内容

  1. MicroSoftのサイトからVisual Studio C++再配布用のモジュールをダウンロードしインストールを行う。 Visual Studio 2015, 2017, 2019, and 2022のArchitectureがX86とX64の2つをインストール。
    https://docs.microsoft.com/en-US/cpp/windows/latest-supported-vc-redist?view=msvc-160

  2. PCを再起動する。

  3. 念の為OuterWildsをアンインストールし再度インストールをする。

※SteamにあるOuter Wildsのコミュニティの投稿によるとこれだけで直るらしいが、私のPCでは直らなかったので続いて以下を実行

  1. Outer WildsのセーブデータをSteamクラウドと同期する設定をオフにする。
  2. ユーザーフォルダ\AppData\LocalLow\Mobius Digital\Outer Wilds以下にあるSteamSavesを適当な場所へ移動(わかりやすくドキュメントとかデスクトップで良い)。
  3. Outer Wildsを起動。

このタイミングでメニューが表示されるようになる。過去のプレイデータがない、あるけどいらないならこれで完了。

過去データがあるなら以下を続ける

  1. 新規のプロフィール作成画面が出てくるので適当にプロフィールを作成(SteamSavesにある既存のプロフィールと名前が被らないほうが良さそう。)
  2. 一旦ゲームを終了し、セーブデータをSteamクラウドと同期する設定をオンに戻す。
  3. ゲームを起動すると先程作成したプロフィールでゲームが起動する。過去のデータで遊びたい場合はプロフィールの切り替えで過去データのプロフィールに切り替えると、 過去のデータで遊べる。

原因

詳しくはわからないけど、どうやらどこかのアップデートのタイミングで新規インストール時にダウンロードするファイルからVisual Studio C++再配布用モジュールが足りなくなったらしい。 足りないけどエラーは出なくてゲームは起動できるから厄介。

それに加えて、バグが起きているときのプロフィールでゲームを起動するとメニューが出ないままになるらしい。 Steamコミュニティへの投稿を見てると、解決後にセーブデータファイルをバグが起きていたときのものに戻してみるとバグが再現したってあった。 だから再配布用モジュールインストール後にプロフィールデータとかのセーブデータが全くない状態でゲームの起動が必要っぽい。

参考

https://steamcommunity.com/app/753640/discussions/0/2568690229016081614/ https://www.reddit.com/r/outerwilds/comments/i13no7/please_help_stuck_on_a_blank_menu_screen/

サイシードプログラミングコンテスト2021(AtCoder Beginner Contest 219)

サイシードプログラミングコンテスト2021(ABC219)に参加しました。

結果

A,B,C問題の3問正解でパフォーマンスが960でした。 D問題でDPをバグらせて原因を探すのに時間がかかりすぎた...

コンテスト中に突然PCがフリーズして焦った。最近ちょっとPCの調子が悪いから困る。買い換えるにしても新しいWindowsが出てからにしたいし。

A - AtCoder Quiz 2

問題文のとおりに処理をする。 if文でどのランクになるか判定して、次のランクの最低点との差を計算して出力する。 入力された点数がすでにエキスパートの時だけは文字列を出力するので例外的に処理が必要。

B - Maritozzo

これも問題文のとおりに処理をする。 Tを1文字ずつ読み取って、それに応じてどの文字列を連結するか判断して処理する。
C++なら読み取ったTの文字から'0'を引くと数値として1,2,3になるのでその後の処理がしやすい。(Sを配列に入れておけばT _ {i} - '0' -1 = 配列Sのインデックスになって楽)

C - Neo-lexicographic Ordering

入力された文字列を別途決められた基準でソートする問題。
手っ取り早くsortで使うようの大小比較用関数を作成してソートした。

D - Strange Lunchbox

問題文を読むとDPかbit全探索で解けそうだなと思いつつ、制約を見て2 ^ {300}は2秒で処理しきれないと判断してDPで解くことにした。 問題の内容的にDP[i][j] = i種類目中j個買った場合のたこ焼きの数とたい焼きの数 といった具合に2次元の配列=pairで処理しようとしてみた。 DPの更新でバグらせて直すのに時間がかかり、直ったけどWAがいくつかあって結局間に合わなかった。最近DPを書いてなかったから初歩的なミスでバグらせてた。

解説を見ると素直にDPを3次元で解けばよかっただけだった。試しにDPを3次元で説いてみるとあっさりACできたしちょっと惜しかったなあ。

AtCoder Beginner Contest217

AtCoder Beginner Contest217に参加しました。

結果

A,B,C,D問題の4問正解でパフォーマンスが786でした。 Cまでは簡単に解けたけどD,Eが難しかった。具体的には自分的にはこれ以上高速化はできないだろうコードでTLEだったので、どこを修正すればもっと早くなるのかさっぱりわからなかった。

A - Lexicographic Order

問題文の通り文字列の大小を比較して適切な文字列を出力する。
ライブラリを使って比較しても良いし、先頭から順番に比較しても良い。文字列の長さは10程度なので先頭からの比較でも十分間に合う長さ。

B - AtCoder Quiz

これも問題文の通りに解いて答えを出力する。 とりあえずマップを使ってどの文字列が何回出たかを数えて、回数が0だった文字列を出力した。
if文を使ってゴリ押しでも解けるとは思う。

C - Inverse of Permutation

ちょっとややこしいけど、順列Qは P _ {i}番目の値がiの順列になる。 P _ {i}を取得する時Q_{P _ {i} }=iとして順列Qを作っていけば良い。

D - Cutting Woods

TLEがなかなか解消できなかった。原因は利用するデータ構造の選択ミスだった...
解法としては切った部分であるx _ {i}の一覧を持っておき、c _ {i} = 1のときはリストにx _ {i}を追加して、 c _ {i}=2の時はx _ {i}前後のxを求めて差分=木の長さを出力する。
最初はxvectorで管理しててc _ {i}=2の時はソートしてから2分探索でx _ {i}を含む両端を求めてた。それでTLEになってたからソートが重いのかなあと思って色々試してみたけど解決せず、二分探索に無駄があるのかなと思ってlowe_boundを使ってライブラリ任せにしてみたけどこれでも解決しなかった。 最終的にはランダムアクセスできないから2分探索やりづらいなあと思いながらSetを使ってx _ {i}を管理して、二分探索だったところはlower_boundを使って処理したらACできた。
今までは、Setはランダムアクセスできない(=インデックスを指定して参照ができない)からインデックスを指定して参照する可能性がある場合は最初からデータ構造の選択から除外してたけど、lower_bound・upper_boundがあるから探索のためにだけ参照したい場合ならSetも問題なく使えるのか。

E - Sorting Queries

こっちは解けそうで解けなかった。最初に書いたコードがTLEしたのが4ケースだけだったので少し工夫すれば解けるかも思ったのがそもそもの間違いだったみたい。
処理内容的にはqueueを使えば良さそうだけど、queueはソートできないから今回の問題では使えなさそう。かと言ってpriority_queueを使うと最初から勝手にソートされるから都合が悪いなあと思ってvectorを使ってみた。 コンテスト中はqueueとpriority_queueの2つを使って管理するのは考えもしなかったから、たぶん今の自分ではどうやっても解けない問題だった。解き方の引き出しか発想力・考察力が足りなかった...

AtCoder Beginner Contest214

AtCoder Beginner Contest214に参加しました。

結果

A,B,C問題の3問正解でパフォーマンスが1249でした。 C問題が早く解けるかどうかでパフォーマスンスがかなり変わるなあ

A - New Generation ABC

問題文のとおりに実装するだけの問題。if文を使って出力する値を制御するだけ。

B - How many?

制約的に3重ループで探索しても問題ないので3重ループで全探索を行う。0 \leq S \leq 100の制約からa,b,cそれぞれ0から100までの範囲で探索すれば良い。最大でもO(10 ^ {6})程度なので時間には収まるので問題なさそう。

C - Distribution

要するに隣の人からもらうのが早いのか直接もらうのが早いのかを計算して答える問題。
1番目から順番に計算しつつ2周分計算する。

D - Sum of Maximum Weights

TLEになって解けなかった問題。 全対地間分の経路計算をして辺の重みの最大値を計算して最後に足し合わせたら良さそう。だけどNが大きくて全対地間分のデータは保持できないので、逆に最大がどの重みの対地間が何組あるのかをmapとかに持たせて、最後に合計を計算すれば処理できそうまでは考えて実装できた。
経路計算するのにダイクストラを使ったけどN回実行しないといけない上に、ダイクストラ1回実行後に各宛先への辺の重み最大値を確認するので結局O(N ^ {2})になってTLEにしかならなかった...

F - Substrings

解き方がわからなかった。具体的には文字列が被る場合の重複分を除く方法がわからなかった。
同じ文字でも元の文字列の場所が異なれば別の文字列して扱ってくれるならとDPで解けるし実装できたけど、答えるべきなのはできた文字列が何種類かなので、DPの途中で文字列の被りを考慮して進める必要がありそうまでは考えた。

AtCoder Beginner Contest213

AtCoder Beginner Contest213に参加しました。

結果

A,B,C問題の3問正解でパフォーマンスが633でした。
最近成績が悪い。精進サボってるのが目に見える形で出てきてるから、日々の訓練は大切なんだなって実感してる。

A - Bitwise Exclusive Or

A問題にしては難しい気がする。ビット演算の知識がないと全探索を始めるところだった。
結論としてはAとBのXORを計算して出力するだけ。
XORは同じ値で2回計算するともとに戻る。例:(X XOR A)XOR A =X
なのでBとAのXORを取ることでBからAを相殺して求めたいCが残ることになる。

B - Booby Prize

Aをソートしたときに大きい方から2番めの値がもともとは何番目のものだったかを求める問題。
点数からもともと何番目の値だったかをマップなりの何らかのデータ構造で持っておいて、点数をソート。その後、何らかのデータ構造で持っておいたデータを参照してもともとの番号を求める。

C - Reorder Cards

結構時間がかかった... 操作自体は難しくなさそうに見えるけど計算量を考えると二重ループとかH,Wそれぞれに対するループはできなさそうでちょっと難しかった。
行と列を独立に考えて良さそうで、それぞれをソートしたときに何番目の値なのかを数えれば良さそうなのはすぐにみえた。だけど、行や列で値が被った時の場合を考えるとああでもないこうでもないと考えこんでちょっと混乱した。

D - Takahashi Tour

深さ優先探索(DFS)をすれば良さそうな問題。DFS自体はスタックを使ってすぐにできたけど、遷移先がなくて戻る場合の処理のうまい方法が見つからず、強引に実装したけど結局いくつかのケースてTLEになっちゃった。
回答例を見るとスタックじゃなくて再帰を使っていたからそもそもの第1歩目を間違えてたみたい。スタックを使ってもうまくやる方法があるんだろうなぁ。

AtCoder Beginner Contest212

AtCoder Beginner Contest212に参加しました。

結果

A,B,C問題の3問正解でパフォーマンスが548でした。 B問題の問題文を誤解しててそこそこ時間を無駄にしてしまった…
あと最近気づいたけど、金曜の夜に夜更しすぎて睡眠時間が足りてないと、コンテスト中は頭の回転が鈍ってパフォーマンスが低くなりがちな気がする。翌日休みでも早く寝ないとなあ…

A - Alloy

問題文の通りif文で処理する。 if文の練習問題かな。

B - Weak Password

入力された暗証番号が以下を満たしていないことを確認する。入力は文字列として受け取り1桁ずつ数字に変換して処理する。

  • 全部同じ数じゃない
  • i桁目とi+1桁目が連続した数になっていない

解いている時は2つ目の条件の意味がわかっていなくてサンプル2がなぜStrongになるのかしばらく考えてた。
任意って好きなものを適当に選んでくらいの意味に思ってたので、サンプル2の1桁目と2桁目が連番になっているから条件満たさないとずっと思ってた。「任意のXX」って「全てのXX」と同じ意味らしい。ずっと間違って認識してた…

C - Min Difference

A _ {i}とB _ {j}全ての組み合わせの中で  |A _ {i} - B _ {j}|の最小値を求める問題。
全組み合わせを愚直に計算しよとするとO(N ^ 2)で最大10 ^ {10}くらいの処理が必要になってTLEになる。 2重ループを工夫して処理が必要そうだったので、[tex:A {i}]はループで処理しつつ、各[tex:A {i}]に対するB _ {j}としては二分探索でA _ {i}に1番近いものを探して計算をした。

E - Safety Journey

もう一工夫が足りなかったのでTLEが解決できなくて解けなかった。
問題文を読むとDPを使えば解けそうだと思ったのでDP[i][j]=i日目に都市jにいる場合の旅の数 として解こうとした。 だけどDPを更新するときに各iに対して2重ループが発生して最終的にO(KN ^ {2}となってTLEになった。
解説を読んでみたらここまでは意図通りでそこからもう一工夫しての処理が必要っぽい。後で解説熟読して復習しとこ。

AtCoder Beginner Contest211

AtCoder Beginner Contest211に参加しました。

結果

A,B,C,D問題の4問正解でパフォーマンスが920でした。 時間ギリギリだったけど久々にD問題まで解けた。結構うれしい。

A - Blood Pressure

問題文の通りに計算を行う。割り算をするときに小数点以下を切り捨てられないように注意すればOK。

B - Cycle Hit

問題文の通り各文字列が何回出てきているかを数える。mapとかの連想配列的なデータ構造を使えば簡単に処理できる。
もしくは力技で、4つの内から2つを選んで文字列が同じかどうかの判定を6通り行う。

C - chokudai

似た問題を解いたことがあったので助かった。C問題にしては難しいような気もするけど、典型的なDPの問題だからC問題でもいいのかなあ。(典型90問の008問で解いてたみたい。)
動的計画法を使って解く種類の問題。DP[Sの先頭からi文字目までチェックした][chokudaiの先頭からj文字目まで選択した]として、 Sの先頭からi番目まで見たときにchokudaiのj文字目の文字列まで選択する場合の通り数を数える。 こうした場合、DP[i][j]はDP[i-1][j]+DP[i-1][j-1]となる。 基本的な考え方は

  • i番目の通り数はi-1番目の通り数をもとに計算できる。
  • i-1番目がchokudaiのj文字目と一致しないならDP[i][j]=DP[i-1][j]となる。(i-1番目までj文字目の選び方が5通りなら次のi番目まで見ても5通りのまま。)
  • i-1番目がchokudaiのj文字目と一致するならDP[i][j+1]はDP[i-1][j+1]+DP[i-1][j]となる。(i番目まででj文字目を選ぶ通り数は、i-1番目でj-1文字目に一致した場合+i-1文字目でj文字目に不一致だった場合となる。)

D - Number of Shortest paths

はじめはDPっぽい問題かなと思いつつ、最終的には幅優先探索を改造して解いた。
問題文を読むと、都市Nまでの通り数は、都市Nに隣接している都市X1,都市X2,・・・への通り数の和になりそうなので、メモ化再帰で都市1に遡りつつ計算して解くか、都市1から都市Nに向かって順番に隣接する都市への通り数を数えていくかで解けそうな気がした。
はじめはメモ化再帰でコードを書いていたけど幅優先探索の方が楽そうな気がしたので途中で方針を変更。 幅優先探索しつつ、その都市への行き方は何通りあるのかを数えていった。 バグ取りしてたら時間がギリギリになったけどちゃんと解けた。