predicateの記述法
c++の理解が浅すぎるので迂闊なことは書けないですが自分へのメモ。
std::sortやstd::transformを使っているとpredicateを指定する状況が自然に生まれてきます。
predicateは関数オブジェクトで表すことができます。関数オブジェクトは()をオーバーロードしたクラスで表すことができます。途中で関数ポインタとの違いが分からなくなって
[*1]を参考にしました。インライン化に関しての理解が浅いので後で[*2]を読みます。
ところでlambda式が評価されるとclosure objectになります[*3]。closure objectは一種の関数オブジェクトになります。よってpredicateはlabmda式で表すことができます。
サンプルコード
int main() { auto compare = [](const std::complex<float> &a, const std::complex<float> &b) -> bool { if(abs(a) == abs(b)) { if(a.real() == b.real()) return a.imag() > b.imag(); return a.real() > b.real(); } else { return abs(a) > abs(b); } }; std::vector<std::complex<float>> seq; seq.push_back(std::complex<float>(0.5f, 1.0f)); seq.push_back(std::complex<float>(0.5f, 0.3f)); seq.push_back(std::complex<float>(4.2f, -1.0f)); seq.push_back(std::complex<float>(0.0f, -2.0f)); seq.push_back(std::complex<float>(2.0f, 0.0f)); seq.push_back(std::complex<float>(-2.0f, 0.0f)); std::priority_queue<std::complex<float>, std::vector<std::complex<float>>, decltype(compare)> queue(compare); for(auto element : seq) { queue.push(element); } std::sort(seq.begin(), seq.end(), compare); std::cout << "std::sort" << endl; for(auto element : seq) { std::cout << element.real() << ',' << element.imag() << std::endl; } std::cout << "std::priority_queue" << endl; for(; !queue.empty(); queue.pop()) { auto element = queue.top(); std::cout << element.real() << ',' << element.imag() << std::endl; } }
出力
std::sort 4.2,-1 2,0 0,-2 -2,0 0.5,1 0.5,0.3 std::priority_queue 0.5,0.3 0.5,1 -2,0 0,-2 2,0 4.2,-1
参考文献
clang_completeでopencvの補完を出すようにする
vimの情報を追っていないのでclang_completeが流行っているのかも定かではないけど自分へのメモ。
開発しているディレクトリに.clang_completeというファイルを作る。中身は下のような感じで。*は適宜変える。
-I/*/opencv/*/include/opencv -I/*/opencv/*/include/opencv2 -I/*/opencv/*/include -I/*/usr/local/include -I. -DLRVTRACK_WITH_OPENCL
っていうかhelp開いてconfigurationの所見たら書いてるのでhelp開く癖つけましょう(自分への戒め)
4. Configuration *clang_complete-configuration*
Each project can have a .clang_complete at his root, containing the compiler
options. This is useful if you're using some non-standard include paths or
need to specify particular architecture type, frameworks to use, path to
precompiled headers, precompiler definitions etc.Note that as with other option sources, .clang_complete file is loaded and
parsed by the plugin only on buffer loading (or reloading, for example with
:edit! command). Thus no changes made to .clang_complete file after loading
source file into Vim's buffer will take effect until buffer will be closed and
opened again, reloaded or Vim is restarted.Compiler options should go on individual lines (multiple options on one line
can work sometimes too, but since there are some not obvious conditions for
that, it's better to have one option per line).Linking isn't performed during completion, so one doesn't need to specify any
of linker arguments in .clang_complete file. They will lead to completion
failure when using clang executable and will be completely ignored by
libclang.Example .clang_complete file: >
-DDEBUG
-include ../config.h
-I../common
-I/usr/include/c++/4.5.3/
-I/usr/include/c++/4.5.3/x86_64-slackware-linux/
Code Thanks Festival B
12月14日(日)、Code Thanks Festival B日程に参加してきました。
勉強会と被ってた & テスト期間が先週まで続いていた & レポートがやばかったのでほとんど準備らしい準備はできずに参加しました。
問題
A問題
int main() { ios_base::sync_with_stdio(0); int A, B; cin >> A >> B; cout << max(A, B) << endl; }
B問題
int main() { ios_base::sync_with_stdio(0); int A, B, C; cin >> A >> B >> C; int D = max(A+B, A*B); cout << max(D*C, D+C) << endl; }
C問題
int main() { ios_base::sync_with_stdio(0); int N, ans = 0; cin >> N; vector<int> v(N); for(int i = 0; i < N; i++) { cin >> v[i]; } int a; for(int i = 0; i < N; i++) { cin >> a; if(v[i] / 2 < a) { ans++; } } cout << ans << endl; }
D問題
int d[1001]; int main() { ios_base::sync_with_stdio(0); int N, T, A; cin >> N >> T; int ans = 0; for(int i = 0; i < N; i++) { cin >> A; for(int j = 1; ; j++) { if(j * A > T) break; d[j*A]++; ans = max(ans, d[j*A]); } } cout << ans << endl; }
E問題
typedef pair<int,int> P; int R, C, N; int field[50][50]; bool ok[50][50]; int x[4] = {0, 1, 0 , -1}; int y[4] = {1, 0 , -1, 0}; int main() { ios_base::sync_with_stdio(0); P s, g; cin >> R >> C; cin >> s.first >> s.second; cin >> g.first >> g.second; s.first--, s.second--; g.first--,g.second--; cin >> N; memset(field, -1, sizeof field); int r, c, h, w; for(int i = 0; i < N; i++) { cin >> r >> c >> h >> w; r--, c--; for(int y = 0; y < h; y++) { for(int x = 0; x < w; x++) { ok[r+y][c+x] = true; } } } for(int i = 0; i < R; i++) { for(int j = 0; j < C; j++) { field[i][j] = -1; } } queue<P> que; if(ok[s.first][s.second]) { field[s.first][s.second] = 0; que.push(s); } for(; !que.empty(); que.pop()) { P p = que.front(); if(p.first == g.first && p.second == g.second) { cout << "YES" << endl; return 0; } for(int i = 0; i < 4; i++) { int ny = p.first + y[i]; int nx = p.second + x[i]; if(0 <= nx && nx < C && 0 <= ny && ny < R && ok[ny][nx] && field[ny][nx] < 0) { field[ny][nx] = field[p.first][p.second] + 1; que.push(make_pair(ny,nx)); } } } cout << "NO" << endl; }
F問題
const long long MOD = 1000000007; long long dp[1001]; int main() { ios_base::sync_with_stdio(0); string X, S, T; cin >> X >> S >> T; int ans = 0; dp[0] =1; for(int i = 0; i < X.size(); i++) { bool f = true; for(int j = 0; j < S.size(); j++) { if(X[i+j]!=S[j]) { f = false; break; } } if(f) { (dp[i+S.size()] += dp[i]) %= MOD; } f = true; for(int k = 0; k < T.size(); k++) { if(X[i+k]!=T[k]) { f = false; break; } } if(f) { (dp[i+T.size()] += dp[i]) %= MOD; } } cout << dp[X.size()] << endl; }
G問題
int dp[501][501]; bool solve(int n, int p) { if(dp[n][p] != -1) return dp[n][p]; if(n <= p) return dp[n][p] = true; bool res = false; for(int i = 1; i <= min(n, p); i++) { if(!solve(n-i, i+1)) { res = true; break; } } return dp[n][p] = res; } int main() { int N, P; cin >> N >> P; for(int i = 0; i <= N; i++) for(int j = 0; j <= N; j++) dp[i][j]=-1; cout << (solve(N, P) ? "first" : "second") << endl; }
H問題
解いてない
2014年度 OPTiM プログラミング勉強会
12月13日土曜日に東京本社で開かれたプログラミング勉強会に参加してきました。
簡単に思い出せる範囲で振り返ろうと思います。
12:30
30分早く本社に着いてしまった。近くのDOUTORで時間を潰した。
13:15
受付をすませ、担当者の指示に従って荷物を置いて席に着いた。
交通費の支払いの書類とかn回ぐらい書き間違えて辛さが高まった。
自己紹介タイム
聞いている限りでは、意外とプログラミングが苦手(というより好きではない)という人が複数人いたことが驚きだった。
どこへ行っても自己紹介はミスるので無難なものを予め用意したほうが良いという結論に至った。
以下の講演のまとめは抜けていたり勘違いしてるところもあると思いますがお許し下さい。
講演1 「企画チームの役割と仕事の話」
講演2 「品質の話」
- 講演者の話し方が上手いと感じたので参考にする。
- 品質の定義「顧客の要求度合い」
- これに顧客の暗黙の要求も考えないといけない。
- 品質と顧客満足度の関連は高い。
- 全体的に見ても開発の流れの話が多くて難しいという印象を受けた。
ディスカッション
懇親会
- 寿司!
- ディスカッションで探してきたサービスを各グループごとに前で発表した。スライドとか使うのかなと思ったけど、ホワイトボードで説明するところがほとんどだった。自分は終始否定意見ばかり行っていた気がして、否定意見出すだけなら簡単なことなので申し訳ないなぁと感じた。
- 全然話せてなかった社員の方々・学生の方々とこの時間で話せてよかった。
- まさか、サイコロ出してくるとは思わなかった(完全に内輪ネタ)
おわりに
プログラミング勉強会という名前は抽象的すぎるし、どちらかというと開発方面の話では無かったが、企画がどういう仕事をしているとかサービスを公開するまでの流れを知れたことは良い経験になったと思う。
こういう勉強会がこれからも開かれるなら積極的に参加したい。しかし、受験生なのでそろそろ受験勉強します(小声)。
Codeforces Round #284 Div2
久しぶりにcodeforcesに出た。Cが幾何で愚直に線分交差判定しようとして謎バグで死んだ。普通に代入して不等式で判別するだけで解けるらしい。数学力の無さ…。
A
int main() { ios_base::sync_with_stdio(0); vector<pair<int,int>> v; int n, x, a, b, ans = 0; cin >> n >> x; rep(i, n) { cin >> a >> b; v.pb(mp(a,b)); } sort(all(v)); int p = 0, m = v[n-1].second; rep(i, v.size()) { for(; p <= m; p += x) { if(p + x >= v[i].first) { break; } } ans += v[i].second - p; p = v[i].second; } cout << ans << endl; }
B
int main() { ios_base::sync_with_stdio(0); int n, l; cin >> n >> l; string a,b,c; map<string, string> m; rep(i,l) { cin >> a >> b; if(a.size() > b.size()) { m[a] = b; } else { m[a] = a; } } cin >> c; cout << m[c]; rep(i,n-1) { cin >> c; cout << ' ' << m[c]; } cout << endl; }
// あとでコード上げる
Code Festival 2014 予選A
精神的にくるものがあったので久しぶりに記事を書く。
予選開始
- A問題開く。通す。
- B問題開く。通す。
- C問題開く。通す。
- D問題開く。貪欲に上から決めていけば解けそう…。
- 少し悩んでも良い実装が思い浮かばない。
- しょうがなく桁DPを書く。
- 提出する。WA...
- 原因がわからないまま終了。
反省
D問題、どうせ通るし30点取りに行かなくてもいいかなと思ってたら嵌って本選に行けない順位になってしまった。戦略ミスだなぁ。死にたさ極まる。
A問題
int main() { string s; cin >> s; s += "2014"; cout << s << endl; }
B問題
int main() { string A; long long B; cin >> A >> B; cout << A[(B - 1) % A.size()] << endl; }
C問題
int f(int x) { return x / 4 - x / 100 + x / 400; } int main() { int A, B; cin >> A >> B; cout << f(B) - f(A - 1) << endl; }
D問題
はまったところは2つあった。
- 10000 1のようなケースを想定できてなかった。
- 全ての状態を考えずにdpの処理部書いてた。
あと、添字ミスもあったしホント辛くなりますよ〜…。
const long long INF = 1e16; const int M = 10; long long dp1[20][4][1 << 12]; long long dp2[20][4][1 << 12]; int main() { string A; long long K, ans = INF; cin >> A >> K; int m = A.size(); for(int i = 0; i < m; i++) { for(int k = 0; k < (1 << M); k++) { for(int b = 0; b < 2; b++) { dp1[i][b][k] = INF; dp2[i][b][k] = INF; } } } for(int i = 0; i < 10; i++) { int n = A[0] - '0'; int S = (i == 0 ? 0 : 1 << i); if(n - i >= 0) dp1[0][(n - i) > 0][S] = n - i; if(i - n >= 0) dp2[0][(i - n) > 0][S] = i - n; } // pos for(int i = 1; i < m; i++) { int n = A[i] - '0'; // carry bit for(int b = 0; b < 2; b++) { // used number for(int k = 0; k < (1 << M); k++) { // next number for(int l = 0; l < 10; l++) { long long borrow = 0; long long add = n - l; bool c = add > 0; int S = (l == 0 && k == 0 ? 0 : k | (1 << l)); int count = __builtin_popcount(S); if(count > K) { continue; } if(add >= 0 && b) { dp1[i][0][S] = min(dp1[i][0][S], (dp1[i-1][b][k] + borrow) * 10LL + add); dp1[i][1][S] = min(dp1[i][1][S], (dp1[i-1][b][k] + borrow) * 10LL + add); } if(add < 0 && !b) continue; if(add < 0) { add += 10; c = add > 0; borrow = -1; } dp1[i][c][S] = min(dp1[i][c][S], (dp1[i-1][b][k] + borrow) * 10LL + add); } for(int l = 0; l < 10; l++) { long long borrow = 0; long long add = l - n; bool c = add > 0; int S = (l == 0 && k == 0 ? 0 : k | (1 << l)); int count = __builtin_popcount(S); if(count > K) { continue; } if(add >= 0 && b) { dp2[i][0][S] = min(dp2[i][0][S], (dp2[i-1][b][k] + borrow) * 10LL + add); dp2[i][1][S] = min(dp2[i][1][S], (dp2[i-1][b][k] + borrow) * 10LL + add); } if(add < 0 && !b) continue; if(add < 0) { add += 10; c = add > 0; borrow = -1; } dp2[i][c][S] = min(dp2[i][c][S], (dp2[i-1][b][k] + borrow) * 10LL + add); } } } } for(int j = 0; j < 2; j++) { for(int k = 0; k < (1 << M); k++) { ans = min(ans, dp1[m-1][j][k]); ans = min(ans, dp2[m-1][j][k]); } } cout << ans << endl; }