JOI予選
http://www.ioi-jp.org/joi/2010/2011-yo-prob_and_sol/index.html
問いてみた.
1 Total Time
足して割るだけ
int main() { int a, b, c, d; cin >> a >> b >> c >> d; const int sec = a+b+c+d; cout << sec/60 << endl; cout << sec%60 << endl; return 0; }
2 Ring
やるだけ.指輪の長さが10固定で,探したい文字列の長さが10以下なので2つ繋げて探すだけでもよさそう.
bool check(const string& key, const string& s) { const int key_len = key.size(); const int s_len = s.size(); for (int i = 0; i < s_len; i++) { for (int j = 0; j < key_len; j++) { if (key[j] != s[(i+j)%s_len]) { goto FAIL; } } return true; FAIL: ; } return false; } int main() { string key; int N; cin >> key >> N; int ans = 0; for (int i = 0; i < N; i++) { string s; cin >> s; if (check(key, s)) { ++ans; } } cout << ans << endl; return 0; }
3 Tile
対称性からとりあえず左上の領域に点を移して考えて,a, b の小さいほうの3の剰余で判断.
int main() { int N, K; cin >> N >> K; for (int i = 0; i < K; i++) { int a, b; cin >> a >> b; --a; --b; a = min(a, N-a-1); b = min(b, N-b-1); if (b <= a) { cout << (b%3)+1 << endl; } else { cout << (a%3)+1 << endl; } } return 0; }
4 A First Grader
まず 2^N を考えたけど N ≦ 100 なので無理.ちょっとしてから DP に気付く.これくらいならすぐ気付いて書けるようにしたい…
int main() { int N; cin >> N; vector<int> v(N); for (int i = 0; i < N; i++) { cin >> v[i]; } vector<vector<long long> > dp(N-1, vector<long long>(21, 0)); dp[0][v[0]] = 1; for (int i = 1; i < N-1; i++) { for (int j = 0; j <= 20; j++) { const int add = j + v[i]; if (add <= 20) { dp[i][add] += dp[i-1][j]; } const int sub = j - v[i]; if (0 <= sub) { dp[i][sub] += dp[i-1][j]; } } } cout << dp[N-2][v.back()] << endl; return 0; }
5 Cheese
一見何通りかチーズ工場を巡る順番があるように思えるけど,よく読むと1から小さい順に巡るしかない.
N回BFSするだけ.
struct P { int i, j; P() {} P(int i_, int j_) : i(i_), j(j_) {} bool operator==(const P& rhs) const { return i == rhs.i && j == rhs.j; } }; int bfs(const vector<string>& grid, const P& start, const P& goal) { const int H = grid.size(); const int W = grid[0].size(); queue<pair<int, P> > q; q.push(make_pair(0, start)); vector<vector<bool> > visited(H, vector<bool>(W, false)); visited[start.i][start.j] = true; while (!q.empty()) { const pair<int,P> p = q.front(); q.pop(); if (p.second == goal) { return p.first; } for (int d = 0; d < 4; d++) { static const int di[] = {-1, 1, 0, 0}; static const int dj[] = {0, 0, -1, 1}; const P t = P(p.second.i + di[d], p.second.j + dj[d]); if (0 <= t.i && t.i < H && 0 <= t.j && t.j < W && grid[t.i][t.j] != 'X' && !visited[t.i][t.j]) { q.push(make_pair(p.first+1, t)); visited[t.i][t.j] = true; } } } return -1; } int main() { int H, W, N; cin >> H >> W >> N; vector<string> grid(H); vector<P> points(N+1); for (int i = 0; i < H; i++) { cin >> grid[i]; for (int j = 0; j < W; j++) { if (grid[i][j] == 'S') { points[0] = P(i, j); } else if ('1' <= grid[i][j] && grid[i][j] <= '9') { points[grid[i][j]-'0'] = P(i, j); } } } int ans = 0; for (int i = 0; i < N; i++) { ans += bfs(grid, points[i], points[i+1]); } cout << ans << endl; return 0; }
6 JOI Flag
わからん…