2020/5/31バチャ反省
百年くらい競プロしていなかったのでバチャをしました。最近レートを上げる気力が無いのでコンテストに出ずあとで解いたりしています。そのうちやる気が出たら再開します。
バチャ
茶色diff*6, 緑diff*4問でやってみました。
結果
1時間9完でした。Lampムズ過ぎてウケる。全体的には茶色でバグらせがちだったかな?
解説
すぬけ君の塗り絵 2 イージー
方針と実装
黒ではなく、白の範囲について考えます。すなわち、白の長方形を構成する4頂点を更新していきます。では実装していきます(雑)
まず、xyそれぞれの左端と右端を初期化します。左端をl、右端をrとすると です。
次に、各aについて問題文の通りに更新していきます。
最終的な4頂点からなる長方形の面積が答えですが、左端が右端を超えているときに辺の長さを0にする処理を忘れるとバグるので気を付けましょう
提出
Attention
西と東を間違えていて一生バグらせていました(恥ずかしい)
方針と実装
なので、全点に対して毎回計算していてはになってしまい間に合いません。こういう時は前計算してから各点について細かい更新をしていくのがセオリーです。
ある人がリーダーになった時に、その人が振り向かせる必要があるのは「自分より西にいて西を向いている人」と「自分より東にいて東を向いている人」です。
一番西にいる人がリーダーの時を考えると、「自分より西にいて西を向いている人」は当然0人です(まず人がいません)。「自分より東にいて東を向いている人」の人数は、「東を向いている人」から自分が東を向いているかどうかを引くことで求められます。
すると、一番西の人がリーダーの時の答えは「0(自分より西にいる西を向いている人数)」 + 「全体のうち東を向いている人数」 - 「自分が東を向いていたら1, 西を向いていたら0」とおけます。
答えを計算したあとは、自分が西を向いていたら「自分より西にいる西を向いている人数」に1を足します。次の人にとって自分は「自分より西にいる西を向いている人」だからです。
二番目以降の人については、
- 自分が東を向いていたら「自分より東の東を向いている人数」を1減らす
- 答えを小さい方に更新する(どのリーダーについても、西西+東東で求められます)
- 自分が西を向いていたら「自分より西の西を向いている人数」を1増やす
を繰り返していくことで、答えが求まります。
提出
怪文書
方針と実装
各文字列で使われている文字と回数を集合に見立てて、その積集合を取ればよいです。
Pythonのsetは重複を許さないので、Counterを使いました。
バグったポイントとしては、更新するときにA-Zの全てのアルファベットについて更新していかないとダメです(初回だけ出てきたアルファベットがあると、それが使用可能と判定されてしまう)
提出
引越しできるかな?
方針と実装
ある目線から見たときに最悪の状態を再現して、それの最大値を取ります。
めちゃくちゃふわっとした言い方になってしまいました。x <= y <= zになるように箱をみて、それぞれの軸について最大値であるようなサイズの箱を用意すればよさそうです(証明ができません、直感で戦っていこうな)
実装するうえでは、荷物のサイズをソートして箱のサイズをmaxで更新していきます。
提出
Streamline
方針と実装
ある点からに行くためのコストはです。ランダムにいくより一番近い点に行ったほうが全体的なコストが抑えられるのは自明なので、Xは事前にソートしておきましょう。
次に、N個の駒があるということについて考えてみます。Xはソート済みなので、当然各駒が交差するような動き方は最適ではありません。[1, 2, 3, 4]と並んでいるときに、(1->3)と(4->2)という動き方をさせるよりは(1->2)と(3->4)の方がコストが小さく済むからです。こう考えると、M個のマスからなるM-1個のコストを、全体でN個に分割できるということが分かります。この時、分割された狭間については移動が必要ないので、その分のコストを消費する必要がありません。(上の例でいう(2->3))
次に、のコスト(M-1個になります)を計算します。すると、この問題は「M-1個のコストがあり、それをN個まで消すことができる。残ったコストの総和を求めよ」と言い換えることができます。
終わりです。
提出
Make a Rectangle
方針と実装
長い奴から使っていきます
提出
Boxes and Candies
方針と実装
まず、左端にx個以上あってはいけません。に調整します。
以降については、を満たすようにを調整していけばよいです。このようにしていくと、「xを超えているときはxに」「超えていないならそのまま」にするので、必要以上に削ること無く条件を満たすことができます。
提出
2017-like Number
方針と実装
となるような配列を計算し(僕はエラトステネスの篩を使いました)、これの累積和を取ります。
この前処理によって、各クエリについて-累積和[l-1]]で計算ができます。
提出
Switches
方針と実装
bit全探索によって全通りのスイッチを試すことができ、それぞれ問題文の通りに計算して全部の電球がついた回数が答えです。
提出
感想
Lampは知らん
水色そろそろ解いたほうがいいな
PAST2-H (1-9 Grid)をDPと拡張BFSで通す
これは何か
PAST2をやっていたらHが全く解けず、競プロ鯖で聴いたら強い方がたくさん教えてくれたので2つの解法についてコードとともに解説する記事です!
問題リンク
問題文と制約
自分の考察
解こうとしながらいくつか考えてたことがありました。そのうちいくつかは的外れだったのですが、一応書いておきます。
(少なくとも方針は)合っていた考察
経路に出てくる1~9のループは一順
問題文より、経路に1~9のループが1巡以上含まれていないといけませんが、これが二巡するとしたら1順目の9の次に最短経路でGに行けばよいので、もし二巡目以降が9->Gの最短経路と同じなら無視してもよく、それ以外なら通らない方が経路が短くなります。
グリッド上のBFSを使って解く
グリッド上のある点sからある点tに行くのは、BFSで最短距離が求められます。
ここで罠があって、いつもグリッド上を探索するときは障害物(つまりは通れない点)があるのでBFSが必要ですが、今回の場合は障害物がないので、最短距離は必ずで表せます。これを使うと後述するDPをすることができます。
BFSをしながらDFSをすると解ける
後述しますがこの発想に至る前に一度「S->1」の最短経路を求める、その1の座標を使って「1->2」の最短経路を求める....といった方針でWAしました。サンプルは通っていたのでもっと一般化することで通せると思い、これにたどり着きました。ざっくり言うと「Sから出発して、1を見つけたらそこからいける2を探す」というのを再帰的に続けて、最終的に「8から出発して、9を見つけたらそこからいけるGを探す」「そのGに至るまでの列挙された経路のコストの最小値が答え」という感じです。
結論から言うとこれは合っているのですが、直感に頼って出てきた方針だったので実装が浮かびませんでした...(競プロ鯖の方の力を借りてこれでACすることもできました。)
間違っていた考察
貪欲にBFS
ダメです。反例は
1S213456789G
です(初手で右に行くのが最適だが貪欲BFSでは左に行ってしまう)
ここで諦める
分からなくなった、というか、「BFSしながらDFS」の実装ができなくて諦めました。
解説を開いたら「DPだよ」って書いてありましたが、グラフ問として解きたかったので競プロ鯖で質問してみました。(DP解法についても下の方にまとめてあります)
- なぜ貪欲BFSが通らないのか
- BFSでやるのはひと工夫いる
ということを教わり、square1001氏がまずは JOI - チーズという問題を解くといい、と教えてくれました。
これは今回の各数字が一つしかないバージョンだったので、僕が考えた貪欲BFSでも通りました。これは目標がN個ある場合、N回のBFSが必要になる解法です
ところがsquare1001氏によると
- この問題は一回のBFSでも解ける
- その解法がこのPAST2-Hにつながるヒントになる
ということだったので、考えてみました。有向グラフとして見るとか、始点から各目標への経路のうち交差している部分を引く、とかいろいろ考えたのですが結局わかりませんでした。ギブアップです。ということで以下答え合わせです。
以下解法の話です(ただし、まずはチーズについての解答です)
グラフを拡張する
「グラフを拡張してBFS」というのが答えでした。最初どういう意味かよくわからなかったのですが、しの氏に丁寧に解説を受けてやっと理解できました。
僕のやった貪欲BFSというのはつまり、点sから点tへの最短経路を求めるたびにグラフを使い捨てて新しいものに変えていました。絵で描くと下のようなイメージです
これを、縦に積みます
ここで大事なのですが、本質的には横に並べても縦に並べても違いありません。これはイメージの問題であって、本当のバグっていた点は「使い捨てにしていた=一枚のグラフで1ペア分の最短経路しか計算していなかった」です。すなわち、この操作の本質は「N個のグラフ」として扱っていたものを「一つのグラフ」として統合して考えるということです。元のグラフから見ると頂点と辺を拡張しているといえるので、「グラフの拡張」と表現されているようです。
さて、では一つのグラフとしてみることで何ができるようになったかを見ていきます。(まだ話は「チーズ」についてです)
先ほどは(S, 1)や(1, 2)などのペアそれぞれについてグラフを用意してBFSをしていましたが、この操作のおかげで一つのグラフの探索で始点から終点までの最短経路が求められるようになっています。
三次元グリッドの探索なので二次元の時と比べて実装を少しだけ変更する必要があります。具体的には
- 頂点の表現方法
- queueへの頂点の追加
が少しだけ変わります。どういうことか説明していきます。
頂点の表現方法
このグラフでは同じグリッドが何枚も重なっています。それぞれのグリッドの頂点は(x, y)の二次元タプルで表されますが、ここに階層の情報を追加する必要があるので、
を表すと定義します。これが一つ目の(小さな、しかし大事な)変更点です
queueへの頂点の追加
もう一つの変更点は、queueへの頂点の追加の際の条件分岐と追加する情報そのものです。僕は普段二次元グリッドに対するBFSの頂点追加部分を以下のように書いています
nxy = (nx, ny) # (x, y)から行ける点 if nxy in seen: continue elif graph[nx][ny] == ".": dis[nxy] = dis[(x, y)] + 1 if nxy not in seen: todo.append(nxy) seen.add(nxy)
これを以下のように変更します
if (nx, ny, level) in seen: continue elif graph[nx][ny] == "X": continue elif graph[nx][ny] == str(N) and level==N-1: return dis[(x, y, level)] + 1 elif graph[nx][ny] == str(level+1): nxy = (nx, ny, level+1) dis[nxy] = dis[(x, y, level)] + 1 if nxy not in seen: todo.append(nxy) seen.add(nxy) else: nxy = (nx, ny, level) dis[nxy] = dis[(x, y, level)] + 1 if nxy not in seen: todo.append(nxy) seen.add(nxy)
5つの条件分岐と処理をざっくり説明すると、
- その頂点が訪問済み
- 何もしない
- その頂点が障害物(侵入不可能)
- 何もしない
- その頂点の値がゴールの値 かつ 今いる階層がゴールの層-1
- その頂点までの最短距離を返す
- (2に当てはまらない かつ )その頂点の値が今いる層+1
- 今いる頂点(x, y, level)から一層上の点(nx, ny, level+1)に辺を張る
- その頂点が訪問済みで無いなら
- その頂点をqueueに追加する
- その頂点を訪問済みにする
- それ以外
- 今いる頂点(x, y, level)から同じ層の点(nx, ny, level)に辺を張る
- その頂点が訪問済みで無いなら
- その頂点をqueueに追加する
- その頂点を訪問済みにする
といった感じです。
ちなみに僕の実装だと制約的にMLEを起こすのでPythonの場合delをしないと通らないという欠陥があります(3次元リストを使うなどでどうにかしてください)
ここまで前置きです
前置きがめちゃくちゃ長くなってしまいました。では実際にPAST2-Hを通していきましょう
僕が把握している二つの解法でこの問題を解いていきます。まずはここまで用意を進めた拡張グラフに対するBFSからです。
拡張したグラフに対するBFS
BFS部分の実装
def bfs_gird(graph, start, x_lim, y_lim): seen = {start} todo = deque() todo.append(start) dis = {start: 0} one_steps = ((1, 0), (-1, 0), (0, 1), (0, -1)) while todo: x, y, level = todo.popleft() for dx, dy in one_steps: nx, ny = x + dx, y + dy if not ((0 <= nx < x_lim) and (0 <= ny < y_lim)): continue if (nx, ny, level) in seen: continue elif graph[nx][ny] == "G" and level==9: return dis[(x, y, level)] + 1 elif graph[nx][ny] == str(level+1): nxy = (nx, ny, level+1) dis[nxy] = dis[(x, y, level)] + 1 if nxy not in seen: todo.append(nxy) seen.add(nxy) else: nxy = (nx, ny, level) dis[nxy] = dis[(x, y, level)] + 1 if nxy not in seen: todo.append(nxy) seen.add(nxy) return -1
簡単に言うと「S(始点)の座標(x, y, level)とグラフ」を与えて、存在するなら「S->1->2->3->4->->6->7->8->9->G」となる経路のうち最短のものの手数をBFSで探索して返します。存在しない場合(この順でGにたどり着けなかった)場合は-1を返します。
実装を見ればわかると思いますが、同じグリッドが10層(始点がS~9)重なっているのでグラフを表す二次元リスト自体を10倍する必要はありません。
提出とソースコード
N, M = map(int, input().split()) graph = [list(input()) for _ in range(N)] from collections import deque def bfs_gird(graph, start, x_lim, y_lim): seen = {start} todo = deque() todo.append(start) dis = {start: 0} one_steps = ((1, 0), (-1, 0), (0, 1), (0, -1)) while todo: x, y, level = todo.popleft() for dx, dy in one_steps: nx, ny = x + dx, y + dy if not ((0 <= nx < x_lim) and (0 <= ny < y_lim)): continue if (nx, ny, level) in seen: continue elif graph[nx][ny] == "G" and level==9: return dis[(x, y, level)] + 1 elif graph[nx][ny] == str(level+1): nxy = (nx, ny, level+1) dis[nxy] = dis[(x, y, level)] + 1 if nxy not in seen: todo.append(nxy) seen.add(nxy) else: nxy = (nx, ny, level) dis[nxy] = dis[(x, y, level)] + 1 if nxy not in seen: todo.append(nxy) seen.add(nxy) return -1 for i in range(N): for j in range(M): if graph[i][j] == "S": start = (i, j, 0) print(bfs_gird(graph, start, N, M))
関数の返す値は問題文で要求されているものそのものなので、Sの座標を探して関数に渡し(ここでにすることを忘れないようにしましょう)、返り値を出力すればよいです。
計算量(合っていないかもしれませんが一応考えます)
ちゃんとした解析の仕方をしらないので直感的に考えます。
ある層iから層i+1までBFSをするとき、最悪なのは始点と終点が対角にある、例えば(0, 0)から(N, M)に思えます。その時は層iのグリッドすべてを探索することになります。僕はBFSの訪問済み頂点の管理にsetを使っているので、1頂点ごとに挿入にかかって全体ででしょうか? なので、10層分探索することを考えても十分余裕そうです。
実際53msで収まっています(Pythonでの話で、PyPyでは97msでした)
DP
実はこれが想定解です。正直検索すればたくさん解説が出てくると思うので後回しにしてしまいました。
公式解説
考察と方針
2点間の距離
かなり前半で示した(そして多分ここまで読むと昔のことなので忘れていると思う)のですが、今回のグリッドは障害物が無いので、ある頂点sから頂点tまでの最短距離はで表されます。これは以下のような関数で求められます
def distance(s, t): return abs(s[0]-t[0]) + abs(s[1]-t[1])
組み合わせの全列挙
素直に考えれば1~9の値を持つ座標をそれぞれまとめて、それらの全ての組み合わせ(1, 2, 3, ..., 8, 9となる組み合わせのことです)に対してコストを計算すれば答えが出ることが分かります。和がSになるN個の数があるとき、それらの総積が最大になるのは(多分)それぞれS/Nとおいたときなので、1~9の各iについてNM/9個あるとすると、計算量は です。これでは到底間に合わないので、これを削っていきます。
各ステップで最適なもののみを選び取る
簡単のために、始点Sには0, 終点Gには10が書いてあるものとします。
0 -> 1
まず初めに、始点の0が書いてあるマスから1が書いてあるマスまでの最短経路を列挙してみます。0のマスの座標が(x_0, y_0)であり、1が書かれたマスがA_1個あるとすると、A_1通りの(座標, Sからの距離)のペアが作れます。0からそれぞれの座標までの最短距離は先ほど示した式で求めることができます。
1 -> 2
次に、1の書いてあるマスから2が書いてあるマスまでの最短経路の組み合わせを考えていきます。1が書いてあるマスはA_1個あり、2が書いてあるマスはA_2個あるとします。1が書いてあるマスから2が書いてあるマスへの最短経路はA_1 * A_2通りあることが分かります。A_1個のiそれぞれについて(2の書いてあるマスの座標, 1の書いてあるマスiからの最短距離)が計算できるからです。
このままでは結局になってしまいます
i -> i+1
ではここで一般化してiが書いてあるマスからi+1が書いてあるマスへの最短経路の数を数えてみましょう。素直に考えると、当然A_1からA_i+1までの総積です。
これを改善するために気づかないといけないのは、「iからi+1への遷移を考えるとき、i-1からiへの遷移がどうであったかは関係がない」ということです。
i-1が書いてあるマスからiが書いてある特定マスへの遷移はA_i-1通りありますが、そのiのマスからi+1の書いてある特定のマスへの遷移の時に使うのは、A_i-1通りある中の最小のコストだけでよい、ということです。なぜなら、どの座標から来ていたとしてもその後の遷移には影響が無いからです。
この性質を使うと、iの書いてあるマスからi+1の書いてあるマスへの遷移について考えるときにA_1からA_iまでの総積通り考えなければいけなかったものが、A_i-1*A_i通りだけ考えればよいことになりました。
説明がすこし複雑になってしまいましたが、この遷移は漸化式に落とし込むことができ、DPをすることができます。
漸化式
のように定義できます。(初期値は十分に大きい値にしましょう)
とするのを忘れないようにしましょう。
提出とソースコード
N, M = map(int, input().split()) graph = [input() for _ in range(N)] def distance(a, b): return abs(a[0]-b[0]) + abs(a[1]-b[1]) points = [[] for _ in range(11)] for i in range(N): for j in range(M): if graph[i][j] == "S": points[0].append((i, j)) elif graph[i][j] == "G": points[10].append((i, j)) else: points[int(graph[i][j])].append((i, j)) inf = float("inf") dp = [[inf for _ in range(M)] for _ in range(N)] start = points[0][0] dp[start[0]][start[1]] = 0 for i in range(1, 11): for point in points[i]: for prev in points[i-1]: dp[point[0]][point[1]] = min(dp[point[0]][point[1]], dp[prev[0]][prev[1]]+distance(point, prev)) goal = points[10][0] print(dp[goal[0]][goal[1]] if dp[goal[0]][goal[1]] != inf else -1)
簡単に解説すると、マスiが書いてある座標をpoints[i]に入れていって、i=1から10まで更新していきます。
最後にDP配列のゴールの座標にアクセスしてinfのままだったら-1, それ以外ならその値を出力します。
計算量解析
最初に述べた通りあるiが書いてあるマスは最悪でなので、毎回それの二乗回ループを回すことになってになります
さいごに
めちゃくちゃ長くなってすいません
優先度付きキュー(二分ヒープ)と隣接リストを使ったダイクストラ法(Python3)
ダイクストラ法については各自参照してください。この記事では実装のみ取り扱います
螺旋本(P309~314)の「優先度付きキューを用いたダイクストラ法」の実装をしたので、それについてソースコードと一緒に書いていきます
提出リンク
実行時間 | メモリ使用量 | コード長 |
---|---|---|
2450[ms] | 90060[kb] | 922[b] |
ソースコード(関数部分のみ)
from heapq import heapify, heappush, heappop inf = float("inf") def dijkstra(graph, start): # graphは隣接リスト vsize = len(graph) dist = [inf] * vsize # 始点からの最短距離 seen = [False] * vsize pq = [] heapify(pq) dist[start] = 0 heappush(pq, (0, start)) # heapではtuple[0]で比較されるのでこの順番で追加する while pq: cost, u = heappop(pq) seen[u] = True if dist[u] < cost: continue for v, w in graph[u]: temp_cost = dist[u] + w if not seen[v] and temp_cost < dist[v]: dist[v] = temp_cost heappush(pq, (dist[v], v)) return dist
計算量
Pythonのheapqの実装は二分ヒープらしいので、Wikipediaを参考にすると、のようです。
経路復元
必要になりそうなのでそのうち書きます
最短全域木を根に向かって追っていけばよさそう?
2020/2/25バチャ反省
バチャリンク
緑問題解けるようになろうと思って緑問題を4問選んでやってみました。
nabefutaとSatoooonくんと3人でやったんですけど、なんとびっくり三人とも30~35分で全完でした
思ったよりだいぶ解けてびっくりしましたね。ペナありならビリですけど
解説を書いていきます
1問目 互除法
考察A
フィボナッチ数列を使います。
なぜフィボナッチ数列がこれに使えるのかというと、問題文にあるコードの
int gcd(int a, int b) { if (b == 0) return a; counter++; return gcd(b, a%b);
の部分に理由があります。
以下では実装と同じ目線で話すために0-indexedを採用しています
フィボナッチ数列を数列Fと置いた際に、gcd(F_i, F_(i-1))
の挙動は以下のようになります。
F_(i-1)
が0の時:終了します。counter
の値は増えませんF_(i-1)
が1の時:gcd(1, 0)
が呼ばれます。counter
の値は1増えますF_(i-1)
が2以上の時:gcd(F_(i-1), F_(i-2))
が呼ばれます(これの証明は、F_i % F_(i-1)
がこの二つの差分(つまりF_(i-2)
)に等しくなるからです。フィボナッチ数列はその定義より一項前の倍を超える値になることがなく、この性質が使えます)。counter
の値は1増えます。- なお、
gcd(F_i, F_(i+1)) [i>1]
が呼ばれた際は、a, bが入れ替わってgcd(F_(i+1), F_i)
が呼ばれます。(この性質により二通りの答えが生まれます)
考察B(公式想定解)
さて、挙動3について考えていきます。
gcd(F_i, F_(i-1))
を呼んだとき、gcd(F_(i-1), F_(i-2))
が呼ばれるわけですが、これはi>2のどのiから始めてもgcd(F_2, F_1)
であるgcd(2, 1)
になります。
ここで、
gcd(2, 1)
はcounter
を1増やし関数を終了させるgcd(F_i, F_(i-1))
がgcd(F_2, F_1)
にたどり着くまでにcounter
はi-2増える
の二点より、gcd(F_i, F_(i-1)) [i>2]
が終了した時点で、counter
はi-1であることがわかります。
よって、counter
をKにするには
gcd(F_(K+1), F_K)
を呼べばいいことがわかります。
即ち、
a=F_(K+1), b = F_K
です。
考察C(別解)
挙動4を使うともう一つの解が見つかります。それは
a = F_(K-1), b = F_K
なのですが、これは挙動4より最初にa, bの反転が起こりcounter
が増加、そこから考察Bの通りK-1増加するので全体でK増加する、ということです。
これだとK=1の時に考察Bのi>2(i-1>1)を破りますが、挙動2よりbが1の時はaに依存せず1回で終わるので、問題ありません。
実装(考察Cを採用)
fib = [1, 1] for i in range(50): fib.append(fib[-1]+fib[-2]) K = int(input()) print(fib[K-1], fib[K])
2問目 Insertion
考察
まず、辞書順で小さいということがどうかを考えます。(
と)
では(
のほうが小さいので、(
ができるだけ先に、)
ができるだけ後に来るようにすればよいです。
これはまぁ簡単で、以下の流れで最適解が出ます。
- Sを左から見ていく
(
があったら変数rに1足す)
があったら、- rが1以上の場合:rを一つ減らす(括弧の対応付け)
- rが0の場合:先頭に
(
を追加(括弧の対応を無理やり生やす)
- さいごにrの数だけ
)
を配列の最後に追加
するだけです。これで括弧の対応を守ったまま(
を最初に、)
を最後に持っていくことができました。
実装
N = int(input()) S = list(input()) stack = [] ans = S[::1] r = 0 for c in S: if c == "(": r += 1 if c == ")": if r > 0: r -= 1 else: ans.insert(0, "(") for _ in range(r): ans.append(")") print("".join(ans))
3問目 引越しできるかな?
考察
今城くんが注文しなければならないダンボールの容積の最小値はいくらでしょうか
という部分から、最適な選択したときに必要となる箱の体積を求めればいいことがわかります。
これは各箱を最適に重ね合わせるときの各軸(x, y, z)の最大値の積であることがわかります(イメージをすると自明だと思います)
では、「最適に重ね合わせる」がどういうことかを考えていきます。
これは、「ソートしてから各軸に対応させたindexに応じて値を更新していく」という風に表せます。具体的には、
- x軸に1番目に大きいものを
- y軸に2番目に大きいものを
- z軸に3番目に大きいものを
という風にしていくことです。何故これが最適かというと、数式での証明が浮かびません。どうしましょう
良いたとえを思いつきました。
例えば箱の中にたくさんの積み木があるとして、それらすべてを十分な時間揺らした場合、それらは最初の乱雑な状態より小さい体積に収まっています。
それと同じで、今回の場合はx > y > zの順に安定するようにする、と考えます。
実装
C = int(input()) a, b, c = 0, 0, 0 for _ in range(C): N, M, L = sorted(list(map(int, input().split()))) a = max(a, N) b = max(b, M) c = max(c, L) print(a*b*c)
4問目Digits in Multiplication
考察
2つの正の整数の組(A, B)がN=A*Bを満たすように動くとき
回りくどい言い方をされていますが、これはつまりNの約数A, Bのペアということです。
つまり、Nの約数のペア全通りについて関数Fを計算し、最小値を出力すればよいです。
Nの約数のペアを求める
一瞬O(N)に見えますが、約数のペアは約数i
についてN//i
でだせるので、sqrt(N)まで探索すればよく、O(sqrt(N))になります。
今回はN = 1010までなので、最悪で105回となり間に合います。
10進数の数の桁を求める
ある10進数の整数Xについて、その桁数はint(log10(X))+1
で求めることができます。
よって関数Fの実装は以下のようになります
def F(A, B): return max(int(log10(A))+1, int(log10(B))+1)
あとは用意したペアすべてについて計算をしながら最小値を更新していけばよいです。
実装
def make_divisors(n): divisors = [] for i in range(1, int(n**0.5) + 1): if n % i == 0: divisors.append((i, n//i)) divisors.sort() return divisors from math import log10 N = int(input()) div = make_divisors(N) def F(A, B): return max(int(log10(A))+1, int(log10(B))+1) ans = 10**9 for a, b in div: ans = min(ans, F(a, b)) print(ans)
終わりに
疲れた~~~!!!今日のバチャは全体的に爆速でとても楽しかったです!今回の解説で一番楽しかったのは1問目の「フィボナッチ数列を使える理由」のところですね、自分で気づいて天才かと思った!!!
2020/2/23 バチャ反省
はじめに
緑上位に行きたいのでバチャを立てて参加しました。 難易度でいうと700~900の茶色上位~緑色下位です。
バチャリンク
結果
nabefutaくんに負けました~~
2完...
1問ずつ通して解説していきます。
1問目 塗り絵
問題文
考察A(問題文をかみ砕く)
解説ACをしました
まず、
(x1, x2)からの距離がr以下の部分を赤く塗ります。
より、赤く塗られた部分=(x1, y1)を中心とした半径rの円であることがわかります。
次に、
x2 <= x <= x3, y2 <= y <= y3を満たす(x, y)を青く塗ります。
より、青く塗られた部分=(x2, y2), (x2, y3), (x3, y2), (x3, y3)を頂点とする長方形であることがわかります。
考察B(問題文の再把握)
考察Aより、問題文の
赤く塗られた部分と青く塗られた部分が存在するかどうかをそれぞれ判定してください。 というものが何を表しているかを考えることができます。
これはそれぞれ
- 赤く塗られた部分がある = 円が長方形に完全に内包されていない
- 青く塗られた部分がある = 長方形が円に完全に内包されていない
という風に言い換えることができます。なぜなら、その色がない時、もう片方の色に完全に重なっている=内包されているといえるからです。
これを踏まえて問題文を見ると、
- 円が長方形に完全に内包されていたらNO, それ以外ならYESを出力
- 長方形が円に完全に内包されていたらNO, それ以外ならYESを出力
をすればいいことがわかります。この時注意しなければならないのが、完全に内包されているかの真偽と出力のYES/NOが逆になっていることです
考察C(条件の整理)
では、どうすれば完全に内包されているかがわかるかを考えていきます。
円が長方形に完全に内包されているか
これは円のxの最大値最小値、yの最大値最小値が長方形のxの最大値最小値、yの最大値最小値に内包されているかを考えればよいです。分割して考えると、
- 円のxの最小値(x1-r)が長方形のxの最小値(x2)以上か
- 円のxの最大値(x1+r)が長方形のxの最大値(x3)以下か
- 円のyの最小値(y1-r)が長方形のyの最小値(y2)以上か
- 円のyの最大値(y1+r)が長方形のyの最大値(y3)以下か
になります。この四点だけ見ればよい理由のイメージとしては、長方形に比べて十分に小さい、長方形に完全に内包された円があるとき、それを拡大していくと最初に長方形の辺に触れるのがこの四点のどれかになるから、といった感じです。
よって、これをすべて満たしていたらNO, 一つでも満たしていなかったらYESを出力します
長方形が円に完全に内包されているか
これは長方形の各頂点が円に内包されているかを見ればよいです。理由としては上と同じで、円に比べて十分に小さい、円に完全に内包された長方形を考えると、それを拡大していくと最初に円に触れるのが各頂点のどれかだからです。
さて、ある頂点(x, y)が円に内包されているかを考えるのは、
(x, y)と(x1, x2)の距離がr以下か
と表すことができます。円は(x1, y1)からの距離がrの範囲なので、当然といえます。 なので、各頂点に対して距離を計算し、r以下かを判定すればよいです。
これをすべて満たしていたらNO, 一つでも満たしていなかったらYESを出力すればよいです。
実装
x1, y1, r = map(int, input().split()) x2, y2, x3, y3 = map(int, input().split()) if (x1 - r >= x2) and (x1 + r <= x3) and (y1 - r >= y2) and (y1 + r <= y3): print("NO") else: print("YES") def check_dis(x, y): dis = ((x - x1)**2 + (y - y1)**2)**0.5 return dis <= r if check_dis(x2, y2) and check_dis(x2, y3) and check_dis(x3, y2) and check_dis(x3, y3): print("NO") else: print("YES")
2問目 □□□□□
問題文
高橋君は大きさ 1 メートル四方のタイルを n 枚持っています。
高橋君はこれらのタイルのうちいくつかを、重ならないように隙間なく並べて大きな長方形を作ろうとしています。
出来上がる長方形はできるだけ正方形に近いほうがよいですが、同時に、使わずに余るタイルの枚数ができるだけ少なくなるようにしたいと考えています。
長方形の縦と横の長さの差の絶対値と、余ったタイルの枚数の和を最小でいくつにできるでしょうか。
考察A(雑な推理)
とりあえず、
- 縦と横の差分だけで見るとa*aの形が一番うれしい
- あまりだけで見るとa*b<=n以下の範囲でa*bが最大になる形が一番うれしい
ということがわかります。
考察B(諦め)
Aより、a*aのかたちに近く、かつa*bを最大化すればいいっぽいことがわかりました。
困りました、これ以上わかりません。
某「全探索するか~」
というわけで、sqrt(n)の周辺±1000位を全探索してみることにしました。
実装
from math import sqrt, floor n = int(input()) ans = 10**10 for i in range(max(1, floor(sqrt(n))-1000), min(n+1, floor(sqrt(n))+1000)): for j in range(max(1, floor(sqrt(n))-1000), min(n+1, floor(sqrt(n))+1000)): if i*j <= n: ans = min(abs(i-j)+n-i*j, ans) else: break print(ans)
ちゃんと通ってうれしいです。
3問目 Rain Flows into Dams
問題文
考察
解説ACをしました。
A_i :=ダムiにある水
X_i := 山iに振った水
降った水の総和とダムにある水の総和が等しいので、
S = A_1 + A_2 + ... + A_N = X_1 + X_2 + ... + X_N
が成り立ちます。 問題文より、
(X_i + X_(i+1)) / 2 = A_i
が成り立ち、2をかけて
X_i + X_(i+1) = 2 * A_i
になります。
Xを求めていきます。
X_1 = S - (X_2 + X_3 + ... + X_N)
ですが、
X_(n*2) + X_(n*2+1) = 2 * A_(n*2)
の性質を使うと、
X_2 + X_3 + ... + X_N =2 * (A_2 + A_4 + ... A_(N-1))
になります。この時、制約よりNは奇数なのでN-1が必ず偶数になり、式が成り立ちます。
これでX_1が求まり、同様にしていけばX_Nまで求まりますが時間計算量O(N2)かかってしまい、TLEしてしまいます。
ここで
X_i + X_(i+1) = 2 * A_i
より
X_(i+1) = 2 * A_i - X_i
X_i = 2 * A_(i-1) - X_(i-1)
の漸化式が立ち、楽に計算ができます。 これでX_2からX_NまでをO(N)で計算することができました
実装
N = int(input()) Alist = list(map(int, input().split())) S = sum(Alist) Xlist = [0] * N Xlist[0] = S - 2 * sum([Alist[_] for _ in range(1, N, 2)]) print(Xlist[0], end=" ") for i in range(1, N): Xlist[i] = 2*Alist[i-1] - Xlist[i-1] print(Xlist[i], end=" ") print()
4問目 Binomial Coefficients
問題文
考察
解説ACです。
証明は以下の通りなんですが、
結論だけ言うと「nCrの最大化をするとき、nはalistのうち最大のもの、rはalistのうち最もn/2に近いもの」というらしいです。
これを実装していきます。 まず、nCrで考えるとnが入力と被ってしまうのでそれぞれm, ansと置きます。mは最大値をとるだけなので、固定です。alistの中から、ansを探索していくことがわかりました。
alistのうち最もa/2に近いものを探すには、差分をsbnとして、十分に大きい初期値を設定してから各aについて
abs(m/2 - a)
がsbn以下かを判定すればよく、sbn以下だったansをaに更新し、sbnをm/2- aに更新していけばよいです。
注意するべき点として、a==mの時は更新できません(i!=jなので)
実装
n = map(int, input().split()) alist = list(map(int, input().split())) m = max(alist) sbn = 10**10 for a in alist: if abs(m/2 - a) < sbn and a != m: ans = a sbn = abs(m/2 - a) print(m, ans)
5問目 Special Trains
問題文
考察
駅Xからの経路を実際にシミュレーションをすればよさそうです。ある駅iから駅i+1に行く手順は共通で、以下の通りです。
- 今の時間がS_iより小さければ、S_iにします、大きければ、そのまま進めます
- now%F_i == 0なら、列車が出ます、それ以外なら、now + F_i - now % F_iまで待つ必要があります。
- 列車に乗るので、now + C_iまで時間が動きます。
これを繰り返すことで、移動がシミュレーションできます。 コードにすると、以下のようになります。
now = max(now, C_i) if now % F_i != 0: now += F_i - F_i % now now += C_i
後はこれを始点iからNまで、iそれぞれについてシミュレーションしていけばいいです。
この時、NからNの経路は存在しないので素直に0を出力します
実装
N = int(input()) CSFlist = [list(map(int, input().split())) for _ in range(N-1)] def calc_time(start): now = 0 for i in range(start, N-1): C, S, F = CSFlist[i] now = max(now, S) if now % F != 0: now += F - now % F now += C return now for _ in range(N-1): print(calc_time(_)) print(0)
終わりに
解説記事をバチャに対して書くのは初めてなんですが、すごい勉強になって最高ですね
これからもできるだけ書いていこうと思います!
キーエンス プログラミング コンテスト 2020 参加記
2020/1/18のキーエンス プログラミング コンテスト 2020の参加記です。
ちゃんと理解して進みたいので解法とか考察を書きます。
---ここでコンテスト---
終わりました。順位表です。
50分AC2完で、レートは微減...ちょっと辛いです。 流れとしては
- Aを通す
- Bを見る
- 「あ、これ本で見たことあるな」となって実装を始める
- 一生通らない
- 順位表見たらみんなC通してるので簡単なのかな?と気づく
- Cがギャグだった
- Bは通らない
でした。
それぞれの問題をどう通したかを書いていきます。厳密性は問うことはあっても責めないでくれると嬉しいです。
A問題
ざっくり言うと「H * Wのマス目を縦横一列ずつ塗りつぶすとき、最小で何回やればNマス以上塗りつぶせるか?」という問題です。
まず、方針として「縦か横を選んでその方向だけを塗りつぶす」ということがわかります。なぜなら、最高効率で埋めるためには「被りが無い」ことが必要(多分)だからです。
よって、縦か横のどちらかを選ぶことになりますが、これはもちろん長い方を選ぶことになります。
なぜなら、その方が短い手数で埋めることができるからです。
長さXの列(または行)を選んでNマスを埋めるのに必要な手数は、ceil(N / X)
で表せます。(ceil
は切り上げ関数)。よって答えは以下のようになります。
H = int(input()) W = int(input()) N = int(input()) big = max(H, W) from math import ceil print(ceil(N / big))
B問題
日本語が弱いので問題文は自分で読んでください。
これを見たときの某「あ、これ見たことあるな、まふゆちゃんがくれた本だ」
なんか名前がついているらしくて、区間スケジュールというらしいです。
方針としては、Xでソートしてから右端を更新していけばいいです。イメージ的には、実際のエリアにロボットを一つずつ置いていくイメージです。
どういうことかというと、
- 与えられたX, Lをペアにしてまとめてから、Xでソートします。
- 右端を適当に設定します。
- XLをループで回していきます。
- その時見ているロボットの左端はX - Lです。右端はX + L + 1です。一つ前の右端が今の左端と被っていなければ(左端 > 右端)、普通に置きます(ansを1増やす)。 被っていたら、右端が小さい方に置換します。それでよい理由は後で説明します。
- さいごにansを出力すればよいです。
右端更新らへんの理由
- もし後の奴のほうが右端が長い場合
- 普通に邪魔なので置きません。右はできるだけ短い方がいいですもんね。
- 前の奴のほうが右端が長い場合
- この場合、右端を短くしたいのは当然として、あとの奴の左端が前の左端より必ず右側にあることがわかるので問題が無く、置換します。
コードはこれでACしました(コンテスト終わって1分後にACしました、カス)
N = int(input()) XLlist = [tuple(map(int, input().split())) for _ in range(N)] XLlist.sort(key=lambda x: x[0]) ans = 1 x, l = XLlist[0] rl = x + (l - 1) for x, l in XLlist: ll = x - l if ll <= rl: rl = min(rl, x + l - 1) else: ans += 1 rl = x + l - 1 print(ans)
C問題
草
二つの和にする必要はありません、SをK個用意して、それ以外は適当に埋めればよいです。ちなみにS + 1とかS - 1にすると10**9, 1で落ちるので、適当に処理してください(値を決めてもよいし、modをとってもよさそうです)
N, K, S = map(int, input().split()) ans = [str(ele) for ele in ([S] * K + [(S - 1) if S != 1 else 10**9] * (N - K))] print(" ".join(ans))
感想
いや悔しい
Bは見えたのに< と <=で通らなかったのは本当につらい
今からABCがあるので頑張ります!
インターンに行った―ン!(強打)
インターンに行ったーんよ。
8/26~9/7までの13(素数)日間、岐阜にある核融合研究所(NIFS)でインターンをしてきました。
疲れた
今は成果発表会が終わって、避難訓練をしてきたところです。暑い
これは何を書くか
体験入学までは書きましたが、インターンでやったこともそれの発展なのでツイートを追って何があったかだけ適当にまとめて寝ます。寝たいんだ
体験入学のブログはここでーす、こっここっこ-!
長いので読んで
注意
ツイートがほとんどなので、いいねとかすると戻っちゃうのでこれをブラウザで開いて読んだほうがいいです
以下適当まとめ(あふぃ)
8/30(体験入学最終日)
中学生のころ友人と2人でずっとバルスゲームやってたんだけど半年くらいやってたからゲーム性高かった
— 変態5号 (@nanigasi_3) August 30, 2019
「バルストス」っていうのが勝負を仕掛ける掛け声で、言われた側も「バルストス」っていったら勝負開始
— 変態5号 (@nanigasi_3) August 30, 2019
主目的は相手の目をつぶすこと。負けた場合は「目が、目がァ~~!!!!」と叫ぶ必要がある
いやマジでこれ楽しいからほんとにこれ楽しいよ主なコマンドは二つ
— 変態5号 (@nanigasi_3) August 30, 2019
+ バルス: バルス。相手にあたると相手の目がつぶれる。相手が言っているのにかぶせると相殺できる。連続使用は2発まで。
+ カウンターバルス: 1バルスに対してかぶせていうと1バルス相殺したうえで1バルスを返す。何もない時にやると自爆で死ぬ。チャージ必要なし
昼休みとかにいきなり「さぁ始まりましたバルストス世界選手権決勝!!!この世界のトップまで駆け抜けてきたのはこの男ォ!某~!!!!」とか言い出していきなり世界選手権決勝(初戦)が始まったり次の日には銀河系最強を決めるとか言ってやってたりした。
俺の反射神経はこのゲームが育てたといっても過言ではない。バルストス!
写真撮ってもらったので貼りました。#nifsintern2019
— 変態5号 (@nanigasi_3) August 30, 2019
⑫で説明してました。写真もらったので貼っておきます pic.twitter.com/UrpD4UQYAN
サチロボの査読来てた pic.twitter.com/RKTfxR8Gkg
— 変態5号 (@nanigasi_3) August 30, 2019
サチロボの査読が来てたので流れで萌えボイス収録してもらおうと思ったけどダメでした。@melon_bread_sha だってさ!パターン増やさないとね!! https://t.co/X3Yf9RVsLR
— 変態5号 (@nanigasi_3) August 30, 2019
今度メロンパンとかで釣ってツンデレボイスが手に入る予定です(わーい)
この日で体験入学終わりだったので一人でパーティしてた。虚無1人でパーティしてる pic.twitter.com/SwaZSUTHmL
— 変態5号 (@nanigasi_3) August 30, 2019
草てぃけ『ブゥン!』(開幕フルスロットル)(重心移動についていけない体重移動スキル)(開幕3秒で爆死)
— 変態5号 (@nanigasi_3) August 30, 2019
草。頑張れ俺周りがディープキスして流れでセックスをしていく中で『眼鏡っ娘と温泉旅行行きてぇ〜!!!』ってツイートしながら40歳になる未来が見えた
— 変態5号 (@nanigasi_3) August 30, 2019
みんな違ってみんな草最近だと中学の同窓会に始まってから呼ばれたり参加するって言ったのに名前が乗って無くてでも参加しなかったら『なんで来ないん!?』みたいな言われたLockさん!? https://t.co/5SE53OolVO
— 変態5号 (@nanigasi_3) August 30, 2019
サチが唐突に超有名おねショタ本をリプしてきて本気でビビりました。エロ漫画とは知らなかったらしいこれですhttps://t.co/sIkOcOoyOa https://t.co/5bTqgJ2BmG
— 変態5号 (@nanigasi_3) August 30, 2019
自分のツイートまとめてるみたいで悲しくなってきた秋無い商いに...飽きない?
— 変態5号 (@nanigasi_3) August 30, 2019
これは自伝です。書いていてつらくなったので書ききれなかった。書いてあるようなことばっか考えてるので女の子と仲良くなれないはてなブログに投稿しました #はてなブログ
— 変態5号 (@nanigasi_3) August 30, 2019
自己紹介-真 - 絶記https://t.co/X6VdNuCqHs
ここらへんで日が変わった
8/31(体験入学最終日の次の日=土曜日)
モバイルバッテリー適当に扱ってたらケーブルが壊れてiPhoneが充電できない事態に。あのwwwモバイルバッテリー振ってコードぬこうとしたら壊れましたwww#nifsintern2019 pic.twitter.com/DF1TP5HZEY
— 変態5号 (@nanigasi_3) August 31, 2019
さすがに死ぬので一週間修行していた山を(徒歩で)降りて人里に向かいました
とりあえず最寄りのスーパーを目指す。そこになかったら詰み
— 変態5号 (@nanigasi_3) August 31, 2019
うるせぇさっさと行け徐行水→飲むと徐行する
— 変態5号 (@nanigasi_3) August 31, 2019
🐒人里に降りたの五日ぶりだわ pic.twitter.com/XKSsQd4CRf
— 変態5号 (@nanigasi_3) August 31, 2019
🐒コンビニ行ったら全ての長さのlightningが売り切れてた
— 変態5号 (@nanigasi_3) August 31, 2019
えっちょっとやだ....キレイ....(さっさと買いに行け) この後ファミマに行ったらあったので普通に買いました#nifsintern2019 pic.twitter.com/b79OWgWS3D
— 変態5号 (@nanigasi_3) August 31, 2019
湖沼の...呼称!
— 変態5号 (@nanigasi_3) August 31, 2019
こしょ攻め?こっしょりこしょこしょ!高尚な交渉
— 変態5号 (@nanigasi_3) August 31, 2019
危険を棄権
— 変態5号 (@nanigasi_3) August 31, 2019
これは言葉に敏感な男インターンでだいぶ疲れているみたいで、今コンビニの『かん・びん』のゴミ箱を見て『並べるセンスがないなぁ...』と思ったけど
— 変態5号 (@nanigasi_3) August 31, 2019
これはギフケルベロスケルベロスおった pic.twitter.com/ChbTaFTV6F
— 変態5号 (@nanigasi_3) August 31, 2019
学名は確かはNanka-atta-hana
で、宿に帰ってきました
これは意味わからん。前後のツイートに田中出てきてないからなんかあったのかもな。誰だか知らんが。田中(バカ...)
— 変態5号 (@nanigasi_3) August 31, 2019
田中のバーカ!
このあと鬼滅の刃見はじめたら面白すぎて日が変わってた。
9/1
気づいたら青春の八月は終わって九月に。彼女できないどころかあった女子がサチとぽっぽさん(部活)しか浮かばない。というかプライベートで外に出た記憶もない。あれ、おれ、なにえお
.
.
.
.
.
.
.
.
.
.
.
とか言ってたらかんたろうがマイクラやろうぜ!とか言ってきたのでバイトのメンバーでマイクラが開始。一時間くらいやったところで通話でバイトの話とか人生の話とか苦手なツイッタラーとか裏垢界隈の話をしてました。久しぶりに色々話した。
終盤は俺が推してるエロ同人の批評会が始まった通話繋ぎながら無音で黙々とエロ漫画を読む会が発足している
— 変態5号 (@nanigasi_3) August 31, 2019
ワイがワイワイしてる間に朝の三時で草ワイワイって単語には『一人称のワイ』『語尾のワイ』『ワイワーイ!(楽しい)』みたいなたくさんの意味が入ってると気づいて感動で泣いてしまった
— 変態5号 (@nanigasi_3) August 31, 2019
↑
これIQ1
--ここらへんで寝落ち--
起床。三食くらいほとんど食べて無くて足が減り始めた(俺はおなかに脂肪が全くないので減るとしたら足くらいしかない)二度寝したらこの時間でした本当にありがとうございました#nifsintern2019 pic.twitter.com/1GtoFEQ1YC
— 変態5号 (@nanigasi_3) September 1, 2019
強く生きるには自分を見失わない心が必要なんで俺変態5号のままなんだ
— 変態5号 (@nanigasi_3) September 1, 2019
変態5号だからか
誰もいなくなったロビーで一人ノスタルジックになってた。#nifsintern2019
— 変態5号 (@nanigasi_3) September 1, 2019
体験入学の時はかなり活気がありましたが今は人がいないので1人で寂しさに耽っています pic.twitter.com/gl6qAnYM8S
まぁ、正直人がいるときは「お前ら体験入学で女子をナンパすんのやめろセックスすんならさっさと部屋いけ」とか思ってたけどな
アイス食べてからウキウキで温泉に行きましたまっちゃで体を冷やしてからの温泉!天才か!?!?、? pic.twitter.com/TS6Qc5fQxY
— 変態5号 (@nanigasi_3) September 1, 2019
--ここらへんで死ぬ--
風呂上がった
— 変態5号 (@nanigasi_3) September 1, 2019
マジでやばい
ほんとに人を殺せる風呂があった
『電気風呂』って銘打ってあるやつで、普通に静電気のやつ(やったことはある)かなと思って入ったのね?
— 変態5号 (@nanigasi_3) September 1, 2019
俺は人より電気を浴びてるから割と耐性はあるはずなんだけど、電極のところに近づけるとマジで体が全体で痙攣して隣に行っちゃったけど戻せなくて、試しを手を近づけたらどんなに頑張っでも閉じた
これまじでやばい
— 変態5号 (@nanigasi_3) September 1, 2019
自分の限界を試して近づけてみたけど、腰が電極?から10cmくらいまで近づくとほんとに体がずっと跳ね上がってた
自分が電気で動いてることをいやでも実感させられたし、あれがこんな温泉にあることに驚いた
— 変態5号 (@nanigasi_3) September 1, 2019
人を簡単に殺せるぞあれ
どうやら筋肉は電気を流すと動く向きが決まってるっぽい(流れる度におなじ動きだった)んだけど、同じ部位に違う方向に動く筋肉が2つ以上あるところもあるみたいで、マジで何も出来ずに肉がちぎれて行くのを必死に押しとどめてた
— 変態5号 (@nanigasi_3) September 1, 2019
手のひらについて5回ほど試行したんですが、どんなに頑張っても閉じる方向に動いて、というか骨が砕ける勢いでギリギリってなってましたね
— 変態5号 (@nanigasi_3) September 1, 2019
やばかった
マジで電気風呂ヤバいエロ漫画でよくある腰を浮かせてビクンビクンってやつ、オーバーだなーと思ってましたが自分が電流によってあれをやらされることになるとは思いませんでしたね(負けたくなかったので何回もチャレンジしましたが毎回なって周りにめっちゃ見られた)
— 変態5号 (@nanigasi_3) September 1, 2019
よくゲームである「バインド!」みたいな束縛魔法あるじゃん?あれ
まじで体が締め付けられて呼吸が止まるし、体が動かなくなるから抜けられない。すとんりばーさんに人体の説明聴きながら何が起こってたかを考察して、リベンジを誓ってご飯食べに行った。(リベンジの話は9/5を見て)
はいどーん(丼)#nifsintern2019 pic.twitter.com/5aAtmSxPoL
— 変態5号 (@nanigasi_3) September 1, 2019
気づいたら帰宿
— 変態5号 (@nanigasi_3) September 1, 2019来ませんでした
寝ました。
9/2
起きました今全裸
— 変態5号 (@nanigasi_3) September 1, 2019
初日から朝ごはんがなくて泣いた(これは言ってくれなかった研究所を恨む)朝ごはん予約しないとダメって言われて予約の話なんて聞いてないのでこれが朝ごはんになってしまいました pic.twitter.com/cvYS3x5GYk
— 変態5号 (@nanigasi_3) September 1, 2019
のでコンビ二に行きました。#nifsintern2019 pic.twitter.com/qd1gyqv1cQ
— 変態5号 (@nanigasi_3) September 1, 2019
でまぁインターン(広義)が始まりました。
先週までは先生がずっといたんですが、なんかいなくなりました。
そうですね、一日に15~30分くらい来て、あとはずっと一人で研究してたえーと、部屋に1人になりました(今日からは基本的に先生はいない)
— 変態5号 (@nanigasi_3) September 2, 2019
見やすくした pic.twitter.com/PNNUA798Fm
— 変態5号 (@nanigasi_3) September 2, 2019
Pythonがグラフ作成で活きましたね。あとデータの管理と簡易計算はExcelが便利。実験する人はExcel慣れたほうがいい天才すぎでは(理論とシミュレーション結果がしっかり一致しています) pic.twitter.com/j17Fsjbdpq
— 変態5号 (@nanigasi_3) September 2, 2019
まずは人間になろうな自分の肉体に勝ちたい
— 変態5号 (@nanigasi_3) September 2, 2019
人間を超越したくない?俺はしたい
たくさんツイートしていましたがシミュレーション中に呟いてたので進捗はしっかり出ていました。お前らが致している間にスライドを進めました。今日の分は終わったのでご飯食べて風呂行きます(今日は電気に勝つ) pic.twitter.com/6F64S7xssy
— 変態5号 (@nanigasi_3) September 2, 2019
とかやってるうちに定時が来たので帰りました
この日はYouTubeでピアノの動画とかヨルシカ(最近好きになってきている)を聴いていたら朝で寝た。致した(自由律俳句)
— 変態5号 (@nanigasi_3) September 2, 2019
9/3
毎朝1人でつらかったワイしかいないんだが
— 変態5号 (@nanigasi_3) September 2, 2019
... pic.twitter.com/VVo0SPlo8j
どうせ話してもうまく説明できないし興味ないだろうしググってもヒットしないので内容は深く言いませんが、buneman instabilityというのをやった。進捗なし
今日やったシミュレーションのやつ
— 変態5号 (@nanigasi_3) September 3, 2019
ポテンシャルと位相空間での移流がしっかりリンクしてる pic.twitter.com/6nCjsYlruT
コンビニで一人で慰めてた。大丈夫、明日はきっとうまくいくよ呼ばれた気がした pic.twitter.com/AgiL8xQuuq
— 変態5号 (@nanigasi_3) September 3, 2019
まぁじに「眼鏡っ娘について書いてよ」といわれたのでブログを書きました。
めっちゃ反響が(身内で)あって、書いた甲斐があるなぁと思いました。ここまで読んでるような人はかなりの暇人だと思うので進む前に読んでください。1分で読めるので怪文書というか排尿
— 変態5号 (@nanigasi_3) September 3, 2019
はてなブログに投稿しました #はてなブログ
眼鏡っ娘について - 絶記https://t.co/hmVe4DIbWM
読んだ?どうせ読まずにこれ見てるだろてか1行下だしな見えるよな。
めっちゃ読まれて、固定にしてた記事を一瞬で越えたえー悲しいことに公開して一時間くらいで固定ツイートのブログを超えました pic.twitter.com/uZ5yIXFKIO
— 変態5号 (@nanigasi_3) September 3, 2019
まぁじに「醤油について書いて」って言われたのでブログを書きました。
いなみちゃんさんに「天才」といわれてフォローされました。天才なのかもしれん。この二個のブログは気に入ってるから読んでくれ同じく1分で読める書けって言われた
— 変態5号 (@nanigasi_3) September 3, 2019
はてなブログに投稿しました #はてなブログ
醤油,show you! - 絶記https://t.co/aT0hVCkqtM
面白くもない長い文章読んでて飽きない?書いてる方も飽きてきてる
9/4
地獄が始まります
— 変態5号 (@nanigasi_3) September 4, 2019
『正直同級生の女子が眼鏡かけて話しかけてくると好きになりそうで精神安定のためにいつもかかとの骨を砕いています。』
— 変態5号 (@nanigasi_3) September 4, 2019
なんでこんなにギャグセンスがあるんだろうね。gift(独.毒)だエンカしてええんか!?
— 変態5号 (@nanigasi_3) September 4, 2019
--研究を頑張った--
--夜が来た--
人生で1番面白い味噌汁渡された(お湯とかはない) pic.twitter.com/3SOtzU3STN
— 変態5号 (@nanigasi_3) September 4, 2019
そろそろ飽きてきました。今自分のツイートを日付で検索して(多すぎるので普通にプロフィールを見ても出てこない)打ってるんですが、RTが出てこないから微妙せやかて駆動開発
— 変態5号 (@nanigasi_3) September 4, 2019
SDD
まぁもう少しだよ
この日の議題は女子とのかかわり方。正直リアルで女子を下の名前で呼ぶの、呼ぶ度に『いや別にそこまで親睦深めてないよな』ってなるからたとえばれいさんとかと会ったら普通に『松田氏〜w』って呼ぶと思う
— 変態5号 (@nanigasi_3) September 4, 2019
ちょっwオタク殿~w氏呼びでござるかwwwいや、なんかネタみたいに扱われてる気がするけど俺は普通に女子を『○○氏』呼びするぞ?
— 変態5号 (@nanigasi_3) September 4, 2019
というか中学の頃は仲のいい女子だいたい氏で呼んでた
これはただの天才まぁじってまぁ人生にマージンが無さそうだなwww
— 変態5号 (@nanigasi_3) September 4, 2019
Momoko_さんのなりすまし出来なさそう
— 変態5号 (@nanigasi_3) September 4, 2019
わかたろうならどうするかな
『本田の皮割とパリパリだった』
— 変態5号 (@nanigasi_3) September 4, 2019
— 変態5号 (@nanigasi_3) September 4, 2019唐突にMomoko_さんなりすまししたりしてた(無理でした)
9/5
この日は9/6の成果発表会に向けたスライド制作
朝からアホ人生を豊かにするコマンド pic.twitter.com/gaa7XBC3yM
— 変態5号 (@nanigasi_3) September 5, 2019
研究所の理論系の人全員に『某が明日インターンの成果を発表するので見に来てな!』みたいなメールがいった(というか俺にも来た)
— 変態5号 (@nanigasi_3) September 5, 2019
丁寧に英語でもついてる
— 変態5号 (@nanigasi_3) September 5, 2019
Ctrl+Shift押しながらホイール回すとターミナルが透明になった遊んでる
— 変態5号 (@nanigasi_3) September 5, 2019
たのしいなこれ pic.twitter.com/deQe6l1HNh
大体データがそろったのでスライド制作開始丁寧なグラフ pic.twitter.com/vTdpxkDNR4
— 変態5号 (@nanigasi_3) September 5, 2019
OCのスタッフなのでTシャツゲット#nifsintern2019
— 変態5号 (@nanigasi_3) September 5, 2019
クソ派手だけどTシャツゲットした! pic.twitter.com/PO0NiIJFO4
めっちゃうれしかった
誤解は生まれそうになったら、ぶった切らないとね
— シャチ (@melon_bread_sha) September 5, 2019
天才的なネタフリ、俺じゃなきゃ見逃しちゃうねそれはもう、豪快にね
— 変態5号 (@nanigasi_3) September 5, 2019
誤解を豪快にぶった切る!
— 変態5号 (@nanigasi_3) September 5, 2019
ってギャグのフリだと思ったけどもしかして違う????
違いましたうん。そこまで考えてなかったわ笑
— シャチ (@melon_bread_sha) September 5, 2019
顎を破壊したりしましたがおおむね平和的に温泉に向かいました。えーそれでは聞いてください。
— 変態5号 (@nanigasi_3) September 5, 2019
『何故か机の上に置いてある髭剃りを顎に押し付けたらヘッドが取れてて顎が砕けガガガガガガガガ』 pic.twitter.com/sgQMngs3qT
左腕持ってかれちゃった
— 変態5号 (@nanigasi_3) September 5, 2019
おいバカ学べ
この前のでなんとなく分かったから『ふっ、私に2度同じ技が通るものか!』って言いながら耐えてたんだけど、調子乗って肘を電極にくっつくレベルに近づけたら左肘がボキッてなっちゃった
— 変態5号 (@nanigasi_3) September 5, 2019
ボキッてなってそのまま退散して『あーやばい絶対やばいよこれ』ってなった
— 変態5号 (@nanigasi_3) September 5, 2019
ばかだ.....肘を返して
— 変態5号 (@nanigasi_3) September 5, 2019
完全に忘れていたけど晩御飯を食べていない
— 変態5号 (@nanigasi_3) September 5, 2019
肉スタ冷やしどこ?
晩御飯の用意の中で悟りを開き勝田
— 高安 基大@Lefixea Inc. (@MotoTakayasu) September 5, 2019
理由もなくデブ活をしました、敗北(体重増加)を知りたい pic.twitter.com/hzIqnQ2z1B
— 変態5号 (@nanigasi_3) September 5, 2019
無理やりなぞの原動力をつけられて300km/h出てる自転車の真似します
— 変態5号 (@nanigasi_3) September 5, 2019
ヴうヴヴヴうヴヴヴヴヴぬぅぅぅぅぅぅうぅうxxxxxxxxxxxxxxxっんんファfんあfんf何ファンファンf何fなファンファンファンf!!!1
本当に寝る
— 変態5号 (@nanigasi_3) September 5, 2019
寝ると言ったら寝る
ねるねるねるねるねるね
9/6
WOWWOW pic.twitter.com/mj33z8N9JA
— 変態5号 (@nanigasi_3) September 5, 2019
今日が地獄の一日
— 変態5号 (@nanigasi_3) September 5, 2019
生き延びるぞ
#nifsintern2019 pic.twitter.com/ha8Y4ol4nQ
— 変態5号 (@nanigasi_3) September 6, 2019
で、練習して時間が近づいてきました。
えーこちら発表者です。20分後に発表始めると聞いていたので部屋の前で待機していますが空いてませんし誰も来ません
— 変態5号 (@nanigasi_3) September 6, 2019
— 変態5号 (@nanigasi_3) September 6, 2019
いやwwwなんでだよwwwでかいわwwwwwww pic.twitter.com/lrFkm4SHLc
— 変態5号 (@nanigasi_3) September 6, 2019
ちなみに一人しかきて無くてそれはそれで泣いてる
— 変態5号 (@nanigasi_3) September 6, 2019
机の下でスマホ触ってたからだれか呼んでくれたのかもしれん。担当の先生も「もしかして誰も来ないんか...???」って顔してる
— 変態5号 (@nanigasi_3) September 6, 2019
お通夜です
インターンさいごがお通夜ですか
— 変態5号 (@nanigasi_3) September 6, 2019
泣いちゃうぜ
— 変態5号 (@nanigasi_3) September 6, 2019
体験入学/インターン担当してくれた先生が三人、それ以外が1人なので聞きに来てくれた方は1名です。4人になった
— 変態5号 (@nanigasi_3) September 6, 2019
まぁ無事終わりました。おわtった~!~!~!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
— 変態5号 (@nanigasi_3) September 6, 2019
もう書くことが無いですね、この後避難訓練と明日のオープンキャンパスの手伝いの内容確認していま研究室でこれを書いています。時間が俺に追いついた。
明日はインターンって感じではないのでブログはここまでとします!終わり!楽しかった!
終わりに
来年もきたいけど金がない