あったこといろいろ

ほぼ自分用備忘録です。

橋・二重辺連結成分分解

この記事は、Competitive Programming Advent Calendar 2016の記事……ではなく、僕のAdCの記事を楽しむための予備知識として書かれた記事です。
ちなみに、僕の担当は明後日です。よろしくおねがいします。



グラフ上の「橋*1」となる辺を求め、これによりグラフを複数の「二重辺連結成分*2」に分解する方法を解説します。
補足を注釈に書いていたりするので、適宜参照して下さい。

アルゴリズム

前置き

橋は、imos法を用いた方法*3やlowlinkを使う方法*4で列挙することができ、橋を取り除いたグラフでDFSをすることで二重辺連結成分に分解できます。
一方ここでは、Spaghetti Sourceのコードに基づいた、DFSをしながら橋と二重辺連結成分をまとめて列挙する方法を解説します。

以下の説明では「DFS木」や「後退辺」といった用語の説明は省きます。
その辺りの知識が不安な場合、npcaの部誌(2014)のP25あたりを読むと良いと思います。(ちなみに、この部誌ではlowlinkを使った橋の列挙方法を解説しています。)

解説

与えられたグラフ上の適当な頂点からDFSを行い、DFS木を作成します。
この作業の途中に、辺(u,v)*5を辿った先がusedである場合、この辺は後退辺であり、頂点u〜頂点vは同じ二重辺連結成分であることがわかります*6
この処理をDFSをしながら繰り返すことで、二重辺連結成分を列挙できます。また、二重辺連結成分に含まれていない辺は全て橋となっているため、橋を列挙できます。
f:id:Yazaten:20160726190852p:plain
u(8,5)が後退辺であるため、頂点5,7,8は同じ二重辺連結成分であることがわかります。

実装

アルゴリズム」の章では大まかな動作を解説しました。ここでは、具体的な実装を解説します。

はじめに、使用するデータ構造についての解説を以下に示します。

変数名 説明
vector<int> order 各頂点に訪れた順番
stack<int> S 既に訪れた頂点のうち、まだどの二重辺連結成分にも割り振られていない頂点の集合
vector<bool> inS 集合Sに各頂点が含まれているかどうかの情報
stack<int> roots 各二重辺連結成分を、DFS木の部分木として見た時の根の集合


適当な頂点を根としてDFSを開始します。
以下の解説では、現在訪れている頂点をcurと呼び、一つ前に訪れた頂点をprevと呼びます。

新しい頂点を訪れる度に以下の動作を行います。

  • order[cur]にorder[prev]+1を代入することで、その頂点に訪れた順番を記録
  • 集合Sにcurを追加し、curを追加したことをinSに記録
  • rootsにcurを追加


使おうとした辺(cur,to)が後退辺である場合(つまり「to!=prev && inS[to]」の場合 )、以下の動作を行います。

  • cur〜toまでの頂点(ただしtoは含まない)をrootsから捨てる


roots.top()の頂点より葉側の頂点の訪問が終了した場合(つまり「cur==roots.top()」の場合)、以下の動作を行います。
なお説明のため、roots.top()の頂点を以下ではnodeと呼びます。

  • nodeと、DFS木上でnodeより1つだけ根側にある頂点を橋として記録する(nodeが根である場合はなにもしない)
  • 一度目にnodeに訪問してから、nodeに戻ってくるまでに訪問した頂点をすべて同じ連結成分分解として記録する。(S.top()がnodeで無い間、topの値を記録し続けることで実現できる。)
  • rootsのtopの格納されている頂点をpopする


上記の動作を行うことによって最終的に、bridge関数の引数であるbrgに橋のリストが、each_bccに二重連結成分のリストが、cmpにある頂点がどの二重連結成分に含まれているかの情報が格納される。


*1:グラフから取り除いた時に連結成分が増える辺

*2:任意の辺を取り除いても連結であるような部分グラフ

*3:二重辺連結成分分解 ライブラリ - ゆらのふなびと

*4:二辺連結成分分解 - コードを短く書く人のブログ

*5:DFS中木上で根に近い方の頂点をvとする

*6:DFS木上の任意の後退辺(u,v)を考えると、vは必ずuの親となります。

ICPC2016アジア地区つくば大会参加記

10/15~16 に行われたICPCつくば大会に、チームmiyazoy72で参加しました。


最終成績は45チーム中42位と、非常に悔しい結果となりました。

チーム練習としては会津さんがvirtual arenaで開いているコンテストに何度か出場していました。
LiveArchiveが壊れていて何を提出してもWAになった回が一番面白かったです。
575.cppはいつも強かったです。

1日目

受付開始30分前頃に会場に到着しました。
受付まではNAISTチーム、電通大チーム、会津大チームの方々とお話をしたりしていました。

周りを見渡すとコンテストの順位表でよく見かける方々ばかりで、このときから既に緊張していました。


プラクティスセッションでは用意していたemacsの設定を記述しましたが、思うように動きませんでした。
余った時間で一人一問を一応AC。
キーボードについては、配列は普段からUSなので問題はなかったものの、少し硬いかなぁという感想でした。
結局僕はあまり実装を担当しなかったので特に問題はありませんでしたが。


会場から筑波大学までは距離があるらしく、バスに乗って移動しました。
歓迎会では他の参加者と交流していました。

ホテルへ移動後は、emacsの設定を調べて、正常に動作する確認をしてすぐ寝ました。


2日目

朝は6時頃に起きました 朝ごはんが美味しかったです。
これはチームメイトとのslackでのやりとりです。
f:id:Yazaten:20161028130849p:plain

会場へはNAISTチームと一緒に移動しました。
会場到着後、コンテスト開始までは特に何もしていませんでした。


コンテスト開始直後はemacs等の設定を記述しました。
前日夜の確認で問題点はわかっていた(フォルダ名を".emacs.d"とするところを".emacs"にしていた)ので気をつけて書きました。
A問題はすぐに書けそうとのことで設定記述中に交代していたので、この時点で1ACでした。

C問題の読解が終わっていたので聞きました。
ある倉庫にたどり着ける荷物の集合は区間で表せることには気づいたのですが、緊張からか考察がなかなか進まず。
嘘解法を noy72 に伝えてしまいWAをもらったりしていました。

ここでB問題が簡単そうと聞きそちらに合流、全探索で適切にやればよさそう。
lazymii に実装をお願いしましたが、サンプルが合わないらしく混乱していたため紙の上で解法を確認。
2時間ほど経ってなんとかAC。時間がかかりすぎてしまった…

C問題は、合流した lazymii が解法を思いついてくれたのでおまかせしました。
A~CまでACするまでに3時間以上かかっており、いつもの調子が出ていないどころの騒ぎじゃないなと思っていました。

ここで選択肢としてはDかEのどちらかを解くというところでしたが、四則演算構文解析やったことなしだったのでDに専念することにしました。
見た瞬間ローリングハッシュだと思ったのですが、多くのチームがWAを出していたり、夏合宿でロリハ問題を軽々とACしていた shora_kujira16 さんのいるチームも手間取っていたため別解法を考えていました。

結局最後まで何も思いつかなかったので、終了間際にハッシュ値を配列に格納しておくO(N^2 logN)のロリハ解をダメ元で提出しました。
配列に格納する都合上MODを10^6にしていたため当然ハッシュが衝突してWAが返ってきました。


冒頭に書いたとおり、結果は 42位 / 45チーム でした。
問題文はほとんどチームメイトが読んでくれたため、その点はほとんど障害になりませんでした。
敗因はハッシュの理解の浅さと緊張だったと思っています。
チームメイトの協力に見合った活躍ができなかった…



コンテスト終了後は、1時間ほど余ったお菓子やドリンクに群がっていました。
コンテストは 8:45~13:45 の5時間開催だったので、とてもお腹が空きました。

その後の懇親会では協賛企業のブースが並んでおり賑やかでした。
司会の方が「あなた方のプログラミングスキルは非常に優秀で…」みたいなことを言っていて、「僕はそうでもないですよ」と思ったりしていました。


解散後は、n_vipさんが主催して下さった二次会に参加しました。
いくつかのチームは海外regionにも参加するらしく、海外チームの話などをしていました。
こういった話はなかなか聞けないので非常に面白かったです。


感想

  • 今まではICPCのアジア地区大会に "進出すること" を1つの目標として競プロを続けて来ましたが、出場チームの人々を見たり会場の空気を感じて、進出は通過点であることを体感しました。
  • ICPCには一応大学の代表として出場しているわけで、悔しいという気持ちとともに恥ずかしいという気持ちになったのが新鮮でした。
  • ICPCに出場できるのは来年で最後になります。NAISTからアジア地区に進出し、今年のNAISTチーム(chasen_no_sato)の取った26位という順位を超えられるよう、今から精進を続けていきます。

ARC056 C問題 部門分け

想定解だと思って書いた解法が、どうやらそうではなかったようなので書きます。

解法

最小カットを使います。

部門を分割することによって幾つかの絆が切られる事を考えると、ある部門を2つに分割するための最小コストは最小カットと等しくなります。

この「2つに分割するための最小コスト」が、部門を1つ増やすことによって得られるスコア K 以上であれば分割を行うとスコアが高くなることがわかります。

このように、部門を最小カットで分割することを繰り返すと最大スコアが得られます。


なお、部門の分割を最小カットで貪欲に切ると良いという証明はできていません。(実験をして大丈夫そうだったので書くと通ってしまいました)(証明は解説を頼ろうと思っていたら全然違う解法が書いてありました)


gist.github.com

ICPCアジア地区つくば大会D問題 「Hidden Anagrams」

※これは参加記ではありません。参加記は別記事で上げます。

問題: AIZU ONLINE JUDGE

問題概要

長さ 4000 以下の S1 と S2 が与えられる。
文字列Sの部分文字列を S' と呼ぶことにする。
「S1' が S2' のアナグラムとなるもの」のうち最長のものの長さを求める。

入力
anagram
grandmother

出力
4

解法

S1とS2のうち短い方の長さをNと呼ぶことにする。
一致判定をする部分文字列の長さLを 1~Nまで変化させながら、各Lにおいて以下の処理を行う。

  • 文字列のアナグラムの一致判定は、文字列を構成する文字のヒストグラムの一致判定と等しいので、部分文字列を長さ26のarrayで表現する。
  • 長さLとなる部分文字列のヒストグラムを記録するmapを用意する。
  • 長さLの、S1の部分文字列ヒストグラムをしゃくとり法の要領で列挙し、mapに記録しておく。
  • この判定によりアナグラムが一致するものが見つかれば、最長の長さの値を更新していく。


空間計算量がO(文字列長)になるので余裕を持って通ります。
mapを使いまわさず、「長さLのヒストグラムは map[L] に格納する」という実装をするとMLEしてしまいました。
つくば会場ではMLが非常に大きかったようなので、本番ではmapを使いまわさなくても通っていたように思います。


gist.github.com

会津合宿2016参加記

9月の17日〜19日に開催された会津合宿2016に参加しました。

会津合宿数日前~前日

🔥🔥🔥大学で一日中作問作業🔥🔥🔥

会津合宿day1

立命館大学セットの作問を担当していました。
講評・解説・入出力ケースは右のリンクから閲覧できます。public - Google ドライブ

会津合宿day2

会津大学セットに参加しました。
Twitterでメンバーを募集していたらctylさんとkazuさんに声をかけていただきました。

コンテスト開始。
A問題がctylさんにより瞬殺されていたがB問題がうまく行っていないらしい。

一方僕はC問題を担当。謎の学園が出てきたが元アニメを知らず悲しかった(あんはぴというらしい)。
曜日ごとに独立だなーと考えて、各曜日においてbitDPした後「i日目にj科目で得られる幸福度の最大値」を求めるDPをする解法を思いつく。
B問題担当のkazuさんとPCを取り合いながら書いたがWA。
しばらくバグが見つからず悩んだが、論理演算のORを"||" ANDを"&&"と書いていた事に気付き修正し提出するとAC。
「bit演算やったことありますか???」という感じ(´・_・`)

Cが通った頃には、BとEが通っていてkazuさんがGを書いているという状態だったので、DとIの概要をctylさんに聞く。

D問題はダイクストラっぽく更新してゴール直前まで行き、ギリギリまで待ってからゴールに渡る解法で解けそうな感じ。

I問題は考察がある程度進んでいて、後は「各頂点から最も遠い頂点までの距離が高速に欲しい」という状態だった。
これ技術奥プログラミングコンテストの不可視境界線では?となったのでcityさんに解法を伝えると良さそうとのこと。

これでDとIの解法が出揃ったが、依然としてGでkazuさんがつらそうにしていた。
この時が一番PCの競争率(?)が高かったように思う。
このときにお菓子を食べに行くと、怒髪先生(ジャッジ側)から「並行して問題解いてるときは一番辛いときだからね。がんばってね。」というありがたいお言葉を頂いた。

その後Iはライブラリを写してもらってすんなりACしたが、DとGはバグが取れずにコンテストが終了してしまった(Gはライブラリが間違っていたらしい)。

コンテスト終了後は駅の方まで移動し懇親会に参加した。
皆で”限界集落”という単語がパワーワードであることに気付きめっちゃ盛り上がった。

会津合宿day3

北海道大学セットに参加しました。
怒髪くんと組みたくなったので探したが遅刻しているらしい。
motiさんに電話をかけてもらってOKの返事をいただく(怒髪先生と連絡をとるのは難易度が高いらしい)。
チームメートがもう一人欲しい気持ちになってTwtterを見ると@tookun_1213さんがメンバーを募集していたのでお誘いした。

問題を各自分担する戦法で僕はA問題を担当。
頑張ってやるだけなのでバグらせないように気をつけながらAC。

実装待ちをしていた怒髪くんがD問題を読んでくれていたので概要を聞く。ありがちだけど時間の制約がデカい。
ライブの開始時刻だけ試すのはすぐ思いついたので累積和+二分探索の方針で実装を固める。
BとCがすんなりACしたようなのでPCを貰って実装を開始する。
場合分けや添字を微妙にミスりながらDをAC。

このあいだに怒髪くんがFの解法を思いついたらしいのでバトンタッチ。
ここでEを読んでいたtookunさんと合流して概要を聞く。
残念ながら僕は何も思いつかなかったが、「意外とゲームはすぐ終了するのでDFSで行けるのでは?」*1という感じと言っていたのでおまかせする。

Gを読む。「角角画伯,かく悩みき」の制約追加版という変わった形式で面白い。
まぁ凸包はするよねみたいなことを話したら、凸多角形の任意の辺を底面とした時の縦横の長さを探索できれば良さそうと教えてもらえた。
キャリパー法で各辺の最遠点が高速に求まる」とか「辺と各点までの横方向の距離は3分探索で求まる」とか話したけれど、「この問題の制約上与えられる多角形の頂点の数はそんなに多くならない」という仮説が出たので時間の都合でそれを実装する…が僕の幾何実装力が低いので途中から怒髪くんに書いてもらう。
どうやら正しかったらしくコンテスト終了6分前にAC。
残り時間でEを書くのは厳しそうだったので、「Gは最悪ケースを作ろうという気持ちになると (多角形の頂点数)≒√(与えられる正方形の数) になりそうだね」みたいな話をしていた。

順位表を見ると、なんとオンラインで2位になっていていた。
普段2位なんて順位は取れないのでチーム戦は偉大だなぁと思った。

おわりに

考察にかなり時間をかけて作った問題が、オンライン参加していたプロによってあっという間に解かれて驚愕した。
去年はそもそもアルゴリズムを知らず考察に携われない問題も多かったが、今年はそういったことは起こらなかったので少し成長を感じた。
チーム戦は最高!組んでくれた方ありがとうございました

*1:行けませんでした

JAG夏合宿2016参加記

9月の2日~5日にかけて開催されたJAG夏合宿に参加しました

1日目 東京到着・ガイダン

夜行バスで早朝に到着したので、yurahunaさん,37dbyeさん,T.M君と新宿のロッテリアでたむろしていました。

ガイダンスまでは時間があったので、模擬地区2012をyurahunaさんと一緒に解きました。
結局二人でDictionaryとMedian Treeを解き、Stack Mazeが解けず。

以下問題のネタバレなので白文字
Median Treeは半信半疑で最小全域木を張ったら通ったのですが、解説を見るとキレイな証明が書いてあり面白い問題だと思いました。

2日目 Central Europe Regional Contest 2014(CERC2014)

チームJag2015Mogichiku( @konjo_p + @nola_suz + @Yazaten )で出場しました。
CERCとはヨーロッパの激戦区の地区予選らしい。

寝坊でチーム決めにTLEしたのですが、2人で出場予定だったkonjo_pさんとnola_suzさんのところに入れてもらうことができました。


開始直後はA~Cをそれぞれ読む方針で僕はB問題を読む。
今いるところから見える一番近い山の斜面はどれですか みたいな問題だったけど斜面の数が結構多くて放置。
あとで聞くと実際ヤバい問題だったらしく良い判断だった。

その間に@konjo_pさんがC問題*1の解法を思いついたらしく書いてもらう。
なんか合わないらしく解法を確認していたが、実装のミスが見つかり無事AC。

その後H問題*2の概要をnola_suzさんに聞き、「なんか組み合わせをDFSで列挙して二分探索でホイみたいな感じですね」と言ったらnola_suzさんが実装をしてくれてAC。(実は列挙しても組み合わせは高々1000以下なので二分探索は不要だった。ごめんなさい。)

その後、僕がD問題*3、他の2人がI問題*4をAC。

この段階で解けそうな問題はF*5かL*6で、Fはチームメンバーが実装してくれそうな感じだったのでLを考える。
区間DPして欲しそうな制約だったがイマイチ区間の持ち方がわからず、いろんな貪欲とかを考えていた。

Lは結局わからないままコンテスト終了だったが、僕を除く2人が熱意でFをACしてくれたので8位といういい感じの順位を取れた


Lは距離と時間を要素にした二次元平面を考えると、「一番遠くで発生する攻撃は必ず打たなければならない」ことからその左側と右側の2つの区間に綺麗にわかれるのでいい感じに区間DPができたらしい。なるほどなぁ

3日目 JAG 模擬アジア地区予選2016

チームBlackSeven( @shora_kujira16 + @yurahuna + @Yazaten )で出場しました。
( 由来はしょらーさん(@shora_kujira16)の言った「NAのB棟7Fはブラック」というローカルネタ )
LINEさんのオフィスを借りての開催で楽しかったです。


2日目同様、開始直後はA~Cをそれぞれ読む方針で僕はB問題*7を読む。
よくあるBFSなのですぐ解ける。A問題*8がACするのを待って連続AC。

C問題*9をyurahunaさんと考えている間にしょらーさんが「Eはこれハッシュでしょ」と言って提出。WAを食らったので諦め、D問題*10を考えてもらう。
するとここでE問題にリジャッジがかかり時間差AC。

D問題の条件を満たす括弧列には規則性があるらしく、いい感じに生成するプログラムをしょらーさんに書いてもらう。実装ミスでWAをもらいつつAC。

F問題以降はわからなかったのでC問題をセグ木を使ってyurahunaさんとペアプロ
時間ギリギリに「サンプル通った!よっしゃいくぞ!」と提出したらめっちゃWAが出て終了♨


模擬地区は解説を聞くと「確かに〜〜」となるような問題が多く面白かったです。

4日目 2015-2016 XVI Open Cup

チームMILK_TEA( @osrehun + @satashun + @Yazaten )で出場しました。
( その辺にミルクティーのペットボトルがあったのでこうなった )
KLABさんのオフィスを借りての開催でした。大人の事情でラブライブの写真を取るのは禁止でした、残念。

前日hecさん(@osrehun)がTwitterで組む人を募集していたので一緒に出ることに。
あとは会場でのランダムマッチングでsatashunさんが加わり、プロ&プロ&僕(´・_・`)という感じになりました。


開始直後はC問題を読んだのですが英語がわからず結局satashunさんに助けてもらった(英語弱者感)
その後読んだF問題では閉路を列挙すればいいと一瞬思ったが、一般にグラフの閉路はめっちゃあるらしくて厳しいらしい。

C問題がいけそう、 D問題もRMQ書けばいけそうという感じでstashunさんとhecさんが取り掛かる。

Aが結構解かれていたので僕が考えていたが計算量を落とす工夫が思いつかない…。
結局hecさんに助けてもらいながらなんとかACしたものの、他の問題には全くと言っていいほど関われなくて申し訳なかった。


F問題の最短経路木を考えると良いと言うのが面白かったです。


おわりに

自分より強い方々とチームを組めたので、いい勉強になりました。
今回の合宿で、ICPC系のセットは「解法のわかりやすい問題をいかに高速に片付けられるか」が大事だと感じました。新しいアルゴリズムを覚えるのも大事ですが、解ける問題をしっかり解く練習もしていきたいです。
夏合宿でチームを組んでくださった方々ありがとうございました。おかげさまで楽しい合宿になりました!


おまけ

夏合宿9日目(家に帰るまでが夏合宿です)にマジカルミライ2016に行きました。
行くのは今年で2度目なんですが、今年も神イベントでした。
興味がある人には超オススメですが、ライブ以降テーマソングを聞くと泣きそうになるという弊害があるので要注意です。

*1:連続する整数の和がNになるような式を求めよみたいな問題

*2: 眠い人が携帯電話で数字を打つ問題

*3:一つの歯車を回すと他の隣接した歯車もまわるので、それぞれがどれくらいどちら向きに回転したかを答える問題

*4:x個の'B'とy個の'W'からなる文字列が与えられるので、'B'の個数:'W'の個数 = x:y となる部分文字列に分解する問題(?)

*5:'?'を含む文字列が3つ与えられるので、それらがsortedであるような'?'の組み合わせの総数を求める問題

*6:敵の攻撃がいっぱい来るのでビームで全部破壊して生き残る問題

*7:お姫様とそれを追う兵士がグリッド状にいて、姫は逃げ切れますか?という問題

*8:読んでない

*9:やる気上位20%しか働かない会社に人間が出たり入ったりする問題

*10:括弧をバランスさせるためにスワップがN解必要な括弧列のうち辞書順最小のものを答える問題

NAIST受験記

NAIST 情報科学研究科 第1回 の試験を受験しました。

結果は合格で、学生宿舎優先入居の権利もいただきました。どの結果が功を奏したのかはわかりませんが、何かの参考になれば幸いです。

NAISTの試験は主に 小論文・数学・英語・面接 からなります。

小論文

A4用紙2枚で取り組みたいテーマを記述し、願書提出時に同封します。

大学での専攻がNAISTでの専攻とは異なるので、卒業研究を小論文用に書き換えることはしませんでした。テーマやアプローチは、スプリングセミナー参加時に志望研究室の学生や先生にお話を伺いながら考えました。

このように準備は春休み頃からしていましたが、実際に手を付けたのは願書提出の3週間ほど前でした。僕は言い回しなどの推敲に時間がかかるタイプなので、書き上がったのは願書提出の1週間ほど前でした。その後、志望研究室の博士後期課程の方のアドバイスを参考に修正し、提出しました。

評価はわかりませんが、納得のいく小論文を提出できたと思っています。

数学

解析・線形代数 の分野から出題され、ホワイトボードを用いて口頭で解答します。

数学に今までまじめに取り組んでこなかったのでイチから勉強しなおしました。
使用した参考書はマセマの「微分積分」と「線形代数」です。勉強を始めたのは願書提出後でした。練習問題を解きつつ参考書の内容を理解し、確認のために演習を解く といった形で勉強を行いました。

本番では、arcsin微分を参考書に載っていた公式を使って解くと微妙な顔をされたり、解析・線形代数 ともに3つ目の小問が全く解けなかったりと、惨敗でした。
甘く見てもせいぜい60点という感じだと思います。

英語

TOEICTOEFLのどちらかを選択し、受験日当日にスコアを提出します。

英語に今までまじめに取り組んでこなかったのでイチから勉強しなおしました。
大学が開講している、TOEIC受験者向けの長期の講座に参加しました。講座参加前は350点ほどでしたが、5月の試験で最終的に600点台を取ることができたのでこれを提出しました。

面接

事前に提出した小論文や受験者の専攻に関する質問に、口頭で解答します。

恒例の3分間プレゼンの内容は、事前に作成し暗記して面接に望みました。どうしても説明したい背景なども含めると時間がギリギリになってしまいましたが、何度も練習をして制限時間を超えないよう心がけました。

プレゼン後の質問は、小論文の内容に関するものが多かったです。プレゼンの一部が正しく伝わっておらず再説明したり、学部の研究の内容や進捗について話をしたりしました。「質問に対してはまず解答を述べる」ことや「質問の意図を理解して簡潔に答える」ということを意識し、あとは自然体で受け答えを行いました。

面接官としっかりとコミュニケーションを取り、十分小論文の内容を伝えられたと思っています。

その他

  • 前泊の必要がある場合、ゲストハウスせんたんを利用することをオススメします。比較的安価な上、綺麗で集中できました。
  • 面接はポスターセッションでの発表と似ていると感じたので、そういった対策をしていくとやりやすいかもしれません。
  • 大学への移動中にモバイルルータを紛失し、スマホを持っていない僕は丸一日インターネット難民を経験しました。貴重な体験でした。