とこはるのまとめ

多分考えたことがまとまっているはずです。きっと。おそらく。

DP俯瞰?

他のDPの記事
http://d.hatena.ne.jp/Tayama/20111210/1323502092
http://d.hatena.ne.jp/komiyam/20111212/1323615687

Typical DP Contest
http://tdpc.contest.atcoder.jp/

  • 基本(1)
  • 基本(2)(有名問題)
    • 最長共通部分列問題(LCS)
    • 編集距離問題
    • 最長増加部分列問題(LIS)
    • 硬貨両替問題
      • 硬貨が1,3,4円だったときにn円で必要な最小枚数を求める問題を指す
    • 最短経路問題?
      • Bellman-ford法
      • Warshall-Floyd法
  • bitDP
    • 巡回セールスマン問題
    • 漸化式がdp[S] = min(dp[T] + dp[U] + f(S,T,U)) ( T,U \subset S, T and U = empty ) (パッと見O(4^n)かかるがO(3^n)で済む形)
    • いくつかの状態を確定したら残りの部分はgreedyで確定するもの
    • ドミノ敷き詰め問題
    • connectedな情報をプラスして持つbitDP
  • 木DP
    • 木の直径
    • (問題)
      • comittee(JOI 春合宿2008)
      • Distribution(JOI 春合宿2009)
      • MultiEndingStory( AOJ2344 )(難)
  • 区間DP
    • 蟻本のBribe the Prisonersなど、大概O(N^3)
    • Monge性を持たせて高速化O(N^2)
      • 最適二分探索木問題
    • 区間+もうひとつの情報でO(N^5)->O(N^4)の高速化 : SRM492D1Med, SRM499D1Med
  • 確率DP
  • 桁DP(DigitDP)
  • 累和を用いるDP
    • 累和で得た結果を中心に使う問題
      • JOI2010本選1, Uva108, APIO2009 Oil
    • 累和を使う高速化
    • imos法(累和の逆演算)
      • Nails(2012JOI本選4), Pyramid(AutumnFest2012)
  • BITやsegmentTreeと組み合わせるDP
  • 行列累乗(二乗反復)
    • 基本は蟻本がくわしい, O(N^3 log k)
    • (E+A+A^2+..+A^k)を求めるもの
    • 上三角/下三角テプリッツ行列, O(N^2 log k)
    • 巡回行列, O(N^2 log k)

追記

http://codeforces.com/blog/entry/8219

GCJ 2013 Qual

http://snuke.hatenablog.com/entry/2013/04/14/164938
ここにsnuke神さんが解説書いてくれています。

C

制約をうまく使って解を全列挙して、クエリが来るたび二分探索をすることを考えます
(制約とは、すべての桁の(数字)^2の総和<=9を意味します)

以下はPracticeで通したコードです。

//(include略)

typedef long long LL;
typedef pair<int,int> PII;
#define MP make_pair
#define REP(i,n) for(int i=0;i<(int)n;i++) 
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++) 
#define ALL(c) (c).begin(),(c).end() 


vector<string> data;

void trans(string s) {
  int n = s.size();
  string k = "";
  for(int i=0; i<106-n; i++) k+="0";
  data.push_back(k+s);
  
}


string two(string s) {
  string ret;
  int n = s.size();
  for(int i=0; i<2*n-1; i++) {
    ret += "0";
  }
  for(int i=0; i<n; i++) if(s[i]!='0') {
      for(int j=0; j<n; j++) {
	ret[i+j] += (s[i]-'0') * (s[j]-'0');
	if(ret[i+j]-'0'>=10)
	  cout<<"hogehoge"<<endl;
      }
  }
  
  return ret;
  
}


void saiki(string t, string s, int sum, int length) {
  if(s.size()+t.size()>=52) return;
  if(sum>=10) return;
  if(t[0]!='0')
    trans(two(t+s));
  
  saiki("0"+t, s+"0", sum, length+1 );
  
  saiki("1"+t, s+"1", sum+2, length+1);
  
}


void init() {
  {
    string t="";
    string s ="2";
    trans("9");
    //    trans("484");
    saiki(t,s,4,1);
    s = "1";
    saiki(t,s,1,1);
    saiki(s,s,2,1);
    s="0";
    saiki(t,s,0,1);
    saiki(s,s,0,1);
    
  }
  
  {
    string s = "2";
    string t = "";
    for(int i=0; i<26; i++) {
      trans(two("2"+t+"0"+t+"2"));
      trans(two("2"+t+"1"+t+"2"));
      trans(two("2"+t+t+"2"));
      t+="0";
    }
    
  }
  sort(ALL(data)); 
}
int solve() {
  string s,t;
  cin>>s>>t;
  
  while(s.size()<=105) s = "0"+s;
  while(t.size()<=105) t = "0"+t;
  
  int ans =upper_bound(ALL(data),t) - upper_bound(ALL(data),s);
  if(binary_search(ALL(data), s)) ans++;
  return ans;
}


int main() {
  init();
  /*
  for(int i=0; i<80; i++) {
    cout<<data[i]<<endl;
    }
  */
  int t;
  cin>>t;
  REP(i,t) {
    int ans = solve();
    cout<<"Case #"<<i+1<<": "<<ans<<endl;
  }
  return 0;
}

D

snukeさんみたいに何の操作をするのが最善かは特に考えませんでした。
ですが方針は同じです。操作を一つ行なってその手の先に解がなければその操作を行わず、解があれば一歩進んでその中で考えます。

解の有無判定は以下のような考えをしました。
とりあえず、「解なし」<=>「ある開けていない箱の鍵をどうやっても手に入れられない」と考えます。
自分が鍵を持っていたらその番号には到達可能です。
次に、ある箱を開ける鍵がKEYAiでその箱にKEYBijが入っているとすればKEYAi->KEYBijに辺を張ってります。
これで到達不可能な鍵があれば解なしだ、というかんじでやりました。

(証明してないのであんま詳しいことは言えない…)

あと、明らかにダメなケース(鍵が足りない)は事前に除きました

REPとforが混じってます

//(include略)

typedef long long LL;
typedef pair<int,int> PII;
#define MP make_pair
#define REP(i,n) for(int i=0;i<(int)n;i++) 
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++) 
#define ALL(c) (c).begin(),(c).end() 

const int MAXKEY = 210;
const int MAXCHEST = 210;
bool usedMain[MAXCHEST];
vector<int> solve() {
  int K,N;
  cin>>K>>N;
  int calcKeys[MAXKEY];
  int keys[MAXKEY];
  REP(i,MAXKEY) {
    keys[i] = 0;
    calcKeys[i]= 0;
  }
  REP(i,K) {
    int p;
    cin>>p;
    p--;
    keys[p]++;
    calcKeys[p]++;
  }
  
  vector<vector<int> > chest;
  vector<int> openKey;
  for(int i=0; i<N; i++) {
    int p,q;
    cin>>p>>q;
    vector<int>tmp;

    p--;
    calcKeys[p]--;
    openKey.push_back(p);
    for(int j=0; j<q; j++) {
      int r; cin>>r; r--;
      tmp.push_back(r);
      calcKeys[r]++;
    }
    chest.push_back(tmp);
  }
  vector<int> noSolution;
  for(int i=0; i<MAXKEY; i++) 
    if(calcKeys[i]<0) 
      return noSolution;
  
  vector<int> ans;
  
  REP(i,MAXCHEST) usedMain[i] = false;
  
  REP(turn,N) {
    bool update = false;;
    REP(chestNum, N) if(!usedMain[chestNum]) if(keys[openKey[chestNum]]>0){
      usedMain[chestNum] = true;
      keys[openKey[chestNum]]--;
      for(int i=0; i<chest[chestNum].size(); i++) {
	keys[chest[chestNum][i]]++;
      }
      bool ok = true; 
      {
	bool usedQueue[MAXCHEST];
	bool usedKeys[MAXKEY];
	queue<int> qu;
	vector<int> graph[MAXKEY];
	REP(i,MAXKEY) {
	  usedKeys[i] = false;
	  usedQueue[i] = false;
	}
	REP(i,N) if(!usedMain[i]) {
	  //	  cout<<"node"<<i<<endl;
	  int s = openKey[i];
	  usedKeys[s] = true;
	  REP(j,chest[i].size()) {
	    int t = chest[i][j];
	    graph[s].push_back(t);
	    //	    cout<<"edge"<<s<<" "<<t<<endl;
	  }
	}
	REP(i,MAXKEY) if(keys[i]>0) {
	  qu.push(i);
	  usedQueue[i] = true;
	}
	while(!qu.empty()) {
	  int cur = qu.front(); qu.pop();
	  //	  cout<<"cur"<<cur<<endl;
	  //	  usedQueue[cur] = true;
	  for(int i=0; i<graph[cur].size(); i++) {
	    int next = graph[cur][i];
	    if(!usedQueue[next]) {
	      qu.push(next);
	      usedQueue[next] = true;
	    }
	  }
	}
	/*
	REP(i,N) cout<<turn<<" "<<i<<" "<<usedQueue[i]<<endl;
	REP(i,3) cout<<keys[i]<<endl;
	REP(i,3) cout<<usedQueue[i]<<" "<<usedKeys[i]<<endl;
	*/
	REP(i,MAXKEY) if(!usedQueue[i] && usedKeys[i] ) ok = false;
	
      }
      if(!ok) {
	usedMain[chestNum] = false;
	keys[openKey[chestNum]]++;
	for(int i=0; i<chest[chestNum].size(); i++) {
	  keys[chest[chestNum][i]]--;
	}
      }
      else {
	update = true;
	ans.push_back(chestNum+1);
	break;
      }
    }
    if(!update) return noSolution;
  }
  return ans;
  
}



int main() {
  int t;
  cin>>t;
  REP(i,t) {
    vector<int> ans = solve();
    if(ans.empty())
      cout<<"Case #"<<i+1<<": IMPOSSIBLE"<<endl;
    else {
      cout<<"Case #"<<i+1<<":";
      REP(x, ans.size()) 
	cout<<" "<<ans[x];
      cout<<endl;
    }  
  }
  
  return 0;
}

xmas contest 2012 G問題について

ネット環境がよい場所に来たので書きます。
日本語が合っているかはよくわかりませんがどうぞ。

問題概要

平面上の格子点にn個の点があって、凸5角形が何個作れるか。
ただし任意の三点は同一直線上に存在しない
n<=400

解法

求めるのは、5点選んでそれの凸包が5点で構成されるもの。
したがって、5点選んで凸包が4点または3点で構成されるものを数え上げることが出来れば答えを求めることができる。

まず、4点の凸包のものについて考えてみる。
選んだ5点で、「ある3点で三角形を作り、内部に1点、外部に1点存在する」ようなものは2通りある。


f:id:tokoharu-sakura:20121228201400p:plain

次に3点の凸包のあるものについて考えてみる。
これも同様に
選んだ5点で、「ある3点で三角形を作り、内部に1点、外部に1点存在する」ようなものは2通りある。

f:id:tokoharu-sakura:20121228201407p:plain

さらに、「ある3点で三角形を作り、内部に1点、外部に1点存在する」ような5点の選び方をすると、上記のいずれかに当てはまります。
したがって、(「ある3点で三角形を作り、内部に1点、外部に1点存在する」ような5点の選び方 )/ 2を計算すれば良いことになります。

愚直に4重ループを回せば以下のようなシンプルなコード(変数名などは雑)ができます

LL yobi(PII A , PII B) {
	LL ret = (LL)A.second * (LL)B.first - (LL)A.first * (LL)B.second;
	return ret;
} 

LL menseki(PII A , PII B , PII C) {
	LL ret = yobi(A,B) + yobi(B,C) + yobi(C,A);
	if(ret<0) ret = -ret;
	return ret;
}

void solve() {
	int n;
	cin>>n;
	vector<PII> coor;
	for(int i=0; i<n; i++) {
		LL x,y;
		cin>>x>>y;
		coor.push_back(MP(x,y));
	}
	LL ans = (LL)n*(n-1)*(n-2)*(n-3)*(n-4) / 120;
	LL tmp = 0;
	LL cntA = 0;
	for(int i=0; i<n; i++) for(int j=0; j<i; j++) for(int k=0; k<j; k++) {
		int cnt = 0;
		LL total = menseki(coor[i] , coor[j] , coor[k]);
		for(int t=0; t<n; t++) if(t!=i && t!=j && t!=k) {
			LL hikaku = 
				menseki(coor[i] , coor[j] , coor[t])
			 + menseki(coor[j] , coor[k] , coor[t])
			 + menseki(coor[k] , coor[i] , coor[t]);
			if(hikaku==total) cnt++;
		}
		cntA += (LL) cnt * (n-3-cnt) ;
	}
	cout<< ans - cntA/2  <<endl;
}


int main() {
	int t;
	cin>>t;
	for(int i=0; i<t; i++) solve();	
	return 0;
}
 

何分かしたら答えが返ってくると思います。
3点選んだ時の内部の点数の列挙ってどうするのが高速になるんでしょう。
すごいうまい方法があってもよさそうだなぁと思ったので誰か是非教えてください。


ちなみにこんな感じの解法を6角形にしてみた問題に適用させようとしましたが、位置関係の場合分けの時点で多すぎて死亡しました。5角形のうまく行きすぎ感がすごかったです。

2012年JAG夏合宿Day2の作問について

この記事について

この記事はhttp://partake.in/events/3fcea6d7-0bab-4597-82db-86439aadb1b9
Competitive Programming Advent Calendar Div2012の12/18の記事です。

コンテストの概要

9/15(土)(11:00-16:00)の http://judge.u-aizu.ac.jp/onlinejudge/contest_standing.jsp?id=JAGSummerCamp12Day2
shioshiota , not , kawatea さんと自分で出題をしました。

作問の機会を与えてくれたeomoleさんに感謝です。

この記事の目的

作問の経験をふまえて、よいコンテストにするにはこう準備すれば上手くいくのではないかなあというポイントについて書いていきます。
3-4人程度での作問を想定しています。

なお、このページに日時などが書いていますが、このようなスケジュールでよく準備ができることは保証できません。多分全体的にもう一週間くらいみておくと余裕を持って作業ができると思います。

もくじ
  • A : いろんな案を出そう
    • A1 : wikiで積極的に書き込む
    • A2 : 問題ドリブンと解法ドリブン
    • A3 : 問題の案が増えれば選択肢も増える
    • A4 : できるだけオフラインで集まろう
  • B : スケジュールは大事
    • B1.ネタを出す時間を作って、最後はオフラインで問題を選ぼう
    • B2.準備するコードは結構多い
    • B3. 問題文を作る時間を計算に入れよう
    • B4.スライドを作る時間も考えよう

A.いろんな案を出そう

今回のコンテストでよかったと思うのは、複数人の相互作用でできあがった問題がいくつかあったことだと思います。

A1.wikiで積極的に書き込む

問題案をたくさん出すという意味でも大事ですが、それに突っ込みを入れるのも相手の考えとのギャップを埋めるのによいと思います。
shioshiotaさんが積極的にやっていた覚えがあります。

A2.問題文ドリブンと解法ドリブン

今回のコンテストの準備では両方のアプローチがあって、7-8割は解法ドリブン、もしくは原案そのままという感じだったように思っていて、残りは問題文ドリブンで出来上がったように思います。

問題文ドリブンで作られた問題はDと、Bの一部分だったように思います。

どちらも問題として出来上がるまでの流れが面白く、作問側としては記憶に残るものでした。
ただ、どちらも最初想定していたよりもだいぶ難しくなってしまったのでコンテスタント側からすれば困った問題だったかもしれません。

A3.問題の案が増えれば選択肢も増える

問題を出しても無駄になってしまうのは惜しいという気持ちはあるが、そこまでケチケチしないほうがよいです。

というのは、今回はICPCの地区予選の練習ということで、バランスや問題の特色(複雑な設定とか重い実装)を似せるほうがよいため、そういう意味で制約が多いものになります。少ない案しか出ていないと問題採択の選択肢が減ってしまっていたと思うので、そのあたりはよかったと思いました。

初回の会合までに完成度の高い問題からそうでないものまで17の案が出されており、自分はこれくらいあれば楽勝だと思っていました...が、実際にはそうはいかずに未決定のものを残しつつ完成した問題から作業を進めることになりました。

A4.できるだけオフラインで集まろう

作問の作業というのはオンラインで作業できることがだいたいですが、それでもオフラインで集まった方が作業が捗ります。
さらに、問題の微調整もしやすいので効率的だと思います。

実際、問題の細部の調整はみんなが集まっているときにできたものがいくつかあります
(例えば、Bの全探索お姉さんの座標系、動き方のルールなど

B.スケジュールは大事

今回のコンテストだと日程はほぼ確定しているのでどのくらいのことをどれくらいにするか逆算しないといけません。
このときには、唯一の経験者だったshioshiotaさんにスケジュールなどの助言をお願いしました。

B1.ネタを出す時間を作って、最後はオフラインで問題を選ぼう

A3の理由で、ネタはたくさんあった方がよいのと、問題採択のときに全員が共通の認識を持てて、問題の修正も容易にできます。

チームが結成されたのは8月上旬(だったはず)で、初めて集まったのは8/24でした。
その日は7問(本番ではA,C,F,G,H,I,J)が修正されつつ選ばれ、2問(本番ではB,D)をもう少し考えよう、という形にしました。

B2.準備するコードは結構多い

それまではあまり意識していなかったのですが、準備するべきコードはたくさんあります。ですので、スケジュールを考えるときにはこれも意識するようにしましょう

hama_duさんの記事http://hama-du.hatenablog.com/entry/2012/12/10/231757 でも触れていますが、入力ジェネレーター、入力チェッカーのほかに、問題によっては出力チェッカーもいります。
問題を解くプログラムだけでも、想定解法(作問者+テスターのふたつ) , 想定誤解法 , 想定TLE解法といった具合に、たくさんコードを書く必要があります。(そうでないと、コンテスト直前に条件を変更するときに柔軟な対応をとれなくなってしまいます。

そのため、自分で作った問題でコードもすぐにかける、という問題でも思っていたよりも時間がかかってしまうと思います。

今回の作問ではこれらのコードの管理はnya3さんのrime(https://github.com/nya3jp/rime/)が使われました。

B3. 問題文を作る時間を計算に入れよう

最初、この作業を「日本語だし楽勝だろう」と自分は完全になめていました。shioshiotaさんに大変だといわれて意外に思っていましたが実際大変でした。

大変なのは具体的には以下の通りです

  • ICPCに似せるとすると問題文が長いこと
  • ICPCの問題は入力変数も多く、その分説明が増えること。
  • 書き方が悪いとcontestantが誤読をしてしまう可能性があるので細心の注意を払う必要がある

誤字どうこうではなく、表現のレベルまで見直さないといけないので結構大変です。
最終チェックはオフラインでやる形になりました。このときに、一斉に読んでみて「この表現はこうした方がよいのでは」などの話をして次の問題へ…という風にやっているとかなりの時間が経過していた覚えがあります。

B4.スライドを作る時間も考えよう

あまり作っていなかったのでいろいろ痛い目を見ました。
特に自分はよいスライドの作り方を心得ていなかったこともあり、
解説当日のスライドはなかなか悲惨だったと思います…。
ちゃんとレビューしてもらうべきでした…。


余談

  • D問題はもとは僕が題名だけつけた問題で、その後notさんを中心に問題が深められていきましたが、コンテスト一週間前に想定解法が誤解法だということがわかって冷や汗をかいたりして、思い出が多いです
  • qnighyさんにAdventCalendarの記事の相談をしたところunion-findの計算量解析を提案してくれましたが、結局やりませんでした。春休みの宿題にさせてください
  • 今年の序盤くらいにはDPの記事を書いてやるーと意気込んでいたりしましたが、いろいろと書いているうちに自分でも収拾がつかなくなってしまい、結局お蔵入りになってしまいました。

チェックした問題

http://d.hatena.ne.jp/anta1/20120730/1343650604 リスペクトanta1さん

今まで見た問題は確実に無理だし、昔見た系は使わないかも
最近もっぱらtopcoder系のまとめにしか使っていない

初見で解けた
○f 自分で解いたが、Practice System TestでFailedしてResubmitした
解説/回答を見て解けた(自分でコードを書いた)
○- 他の人のコードをほぼ丸写し
○' 昔やってあったが、それが初見かどうかとかはわからない
解説/回答を見てなんとなくわかった気がするが、自分のコードを書けてない
△? わかったかどうか微妙な所
△- ちょっと解説を見てへえと思っただけくらい
% 近似解もスコアのつく問題で、良いスコアではない
× 見ただけで出来てない。回答を見てもわかってない
記録がないし、昔解いたかもしれないが忘れた

SRM

div1Medium

問題 状態 pt/max 解いた日時 コメント
463 326.37/500 2013/3/19 規則性に気づくのに時間がかかる。1.1以上にされると死にそう
464 no/550 13/3/19 答えみたら簡単だった
465 ○f 180.00/600 13/3/19 LLに直したら通った
466 ○' まぁすぐ思いついたし
467 晩飯を挟んだ
468 ○f 150.00/500 13/4/2 前処理/コーナーケース
469 (null)/500 13/4/2 方針の時点で死亡
470 355.00/500 13/4/2 前回は346だったらしい
471 217.69/500 13/4/3 解法はすぐだが迷った
472 (null)/600 13/4/3 数え上げ能力の不足
473 416.06/500 13/4/4 easy.
474 ○f 240.16/500 13/4/4 easyなのに誤読+resubmit
475 ○f 180.00/600 13/4/4 6submit
476 ○f 165.00/550 13/4/7 確率bitDP,corner , 要再挑戦
477 ○f 175.58/500 13/4/9 2resubmit, 制約読み違え, 条件忘れ
480 ???/450 13/5/18 medとは思えない簡単さ
481 390?/500 13/8/3 easy.初期化バグ
486 ???/450 13/9/30 多分再帰でも書ける。シンプル確率
487 面倒なだけっぽいので飛ばし
491 180/600 13/10/5 解くのに時間がかかる。TLE食らった
492 179.91/550 13/10/6 時間かかる。良問
493 面倒なだけっぽいので飛ばし
494 209.4/500 13/10/7 自分が弱いパターンの問題っぽい
495 普通に意味取り違ってた。あと詰めあまい(書いてない)
496 考えればわかるが解くのは省略
497 めんどい
498
499 ○' 165/550 13/12/15 類題ということに気づかず非常に悔しい
501 329.87/500 13/12/22 やりやすいDP
502 ? 昔解いてた。解法も(例のGreedyをわかってれば)簡単。
503 288.43/500 13/12/22 この界隈によくある確率問題
504 ○f 150/500 13/12/22 誤読+resubmit. swapとflipは違います
506 13/12/29 簡単
504.5 450?/550 13/12/30 Medとは思いがたい簡単さ
507 ◎f 150/500 13/12/30 SimpleMathだが、ハマってしまった。ありうるパターンを列挙しきれていなかった。
513 --/500 14/2/6 確率。詳細を詰め切れなかった

Div1Hard

問題 状態 pt/max 解いた日時 コメント
466 △? わからん
467 わからん
473 432.44/1000 2013/4/4 複雑数え上げ
474 わかんね
481 317.05/900 2013/8/4 誤読・方針迷走
487 ○' ???/950 ??? かんたんなD1H
491 わからん
494 flip,2のべき乗のパターンだけ把握
495 295?/950 13/10/8 面白い対応付けのできる問題
496
497 ○' 解いたことはあるが忘れた
498 13/12/15 答えを見て一応理解したつもり(だがすぐに忘れそう
499 13/12/15 解法はわかるが実装は無理な気がする
506 13/12/29 惜しいかもしれないが結局解けず解説を見る
504.5 13/12/29 一目簡単
512 ○f 13/12/31 自分で考えれてよかった。数え上げ。
590 300/900 2013/9/9 フロー
612 328/900 14/3/27 簡単なHard(時間かかった

Codeforces

識別子 問題 タイトル 状態 pt/max 解いた日時 その他 コメント
172Div1 A 2013/3/10 初見では場合分けが必要。これに適したライブラリがあるので使えるようにしたいところ
172Div1 B 2013/3/10 綺麗な構造。priority_queueとリストを使えばさらさらとかける
172Div1 C 2013/3/10 式が綺麗だが、なぜこのように解けるのかがわからない。深さの逆数の総和

OI系

識別子 問題 タイトル 状態 pt/max 解いた日時 その他 コメント
APIO 2007 backup 100 2013/3/3 リスト構造+priority_queueの面白い問題

一般OnlineJudge系(POJ,SPOJ,ZOJ,AOJ,CodeChef)

識別子 問題 タイトル 状態 pt/max 解いた日時 その他 コメント
AOJ 1185 チョコレート分割 2013/3/11 スキー合宿のバスの中で考えてたら解けました

特殊(?)OnlineJudge系(HackerRank,ProjectEuler(ネタバレしないように))

||識別子|問題|タイトル|状態|pt/max|解いた日時|その他|コメント|