【AOJ 2619】Thread Tree
問題
Thread Tree | Aizu Online Judge
方針
- 木を作って順に辿って出力する.
- 英語つらいなって思ったけどそんなに難しくなかった.(これは方針ではない)
コード
#include<bits/stdc++.h> #define rep(i, n) REP(i, 0, n) #define REP(i, a, n) for(int i = a ; i < (int)n ; i++) #define pb push_back using namespace std; struct TREE { int _d; string _name; vector<TREE*> _v; TREE(string name, int d){ _name = name; _d = d; } void add(TREE* t){ _v.pb(t); } void print(){ rep(i,_d) cout << "."; cout << _name << endl; rep(i, _v.size()){ _v[i]->print(); } } }; signed main(){ int n; int k1, k; string m1, m; TREE* v[1001]; TREE *t, *root; cin >> n; cin >> k1; cin >> m1; root = t = new TREE(m1, k1); v[1] = t; REP(i, 2, n+1){ cin >> k >> m; t = new TREE(m, v[k]->_d+1); v[k]->add(t); v[i] = t; } root->print(); }
木を作るのに苦労するなど. まだまだですね.
AtCoder Beginner Contest #60
問題はこちら. abc060.contest.atcoder.jp
問題A:Shiritori
文字列A, B, Cが3つ与えられた時, それらがしりとりになっているか判定せよ.
#include <iostream> using namespace std; signed main(){ string a, b, c; cin >> a >> b >> c; if(a[a.size()-1] == b[0] && b[b.size()-1] == c[0]) cout << "YES" << endl; else cout << "NO" << endl; }
問題B:Choose Integers
正の整数A, B, Cが与えられる. 正の整数を幾つか選び, をれをBで割った時, 余りがCとなるように整数を選ぶ事ができるか出力せよ. ただし, 正の整数はAの倍数でなければならない.
#include<iostream> using namespace std; signed main(){ int a, b, c; cin >> a >> b >> c; int tmp = a; int mod = 0; bool flag[101]; fill(flag, flag+100, false); mod = tmp % b; do{ flag[mod] = true; if(mod == c){ cout << "YES" << endl; exit(0); } tmp += a; mod = tmp % b; }while(!flag[mod]); cout << "NO" << endl; }
問題C:Sentou
スイッチを押すと, T秒お湯が出る. スイッチを押すタイミングが与えられるので, 合計何秒間お湯が出たかを出力せよ. お湯が出ている状態でスイッチを押すと, T秒延長されるのではなく押した瞬間からT秒間お湯が出力されるという点に注意.
#include<bits/stdc++.h> #define rep(i, n) REP(i, 0, n) #define REP(i, a, n) for(int i = a ; i < (int)n ; i++) using namespace std; int n, t; int data[200001]; signed main(){ cin >> n >> t; fill(data, data+200000, 0); rep(i, n){ cin >> data[i]; } int end = 0; int start = 0; int ans = 0; rep(i, n){ if(data[i] < end){ end = data[i] + t; }else{ ans += (end - start); start = data[i]; end = data[i]+t; } } ans += (end - start); cout << ans << endl; }
問題D:Simple Knapsack
ナップサック問題. ただし,
という制約がついている. このwの制約を利用することで全探索をすることができる. 各重さごとにvectorにpushしておき, それらをどれだけ使うかを4重ループにして試す.
#include<bits/stdc++.h> #define rep(i, n) REP(i, 0, n) #define REP(i, a, n) for(int i = a ; i < (int)n ; i++) #define ALL(v) v.begin(), v.end() #define pb push_back using namespace std; typedef long long ll; ll N, W; signed main(){ ll w1, v1, _w, _v; cin >> N >> W; cin >> w1 >> v1; vector<ll> v[4]; v[0].pb(v1); REP(i, 1, N){ cin >> _w >> _v; v[(_w - w1)].pb(_v); } rep(i, 4){ sort(ALL(v[i])); reverse(ALL(v[i])); } ll ans = 0; rep(i, v[0].size()+1){ rep(j, v[1].size()+1){ rep(k, v[2].size()+1){ rep(l, v[3].size()+1){ _w = 0; _v = 0; rep(ii, i){ _w += w1; _v += v[0][ii]; } rep(ii, j){ _w += (w1+1); _v += v[1][ii]; } rep(ii, k){ _w += (w1+2); _v += v[2][ii]; } rep(ii, l){ _w += (w1+3); _v += v[3][ii]; } if(_w <= W){ ans = max(ans, _v); } } } } } cout << ans << endl; }
rateが868(highest)になった. かなり低いけど地道に頑張っていこう.
【AOJ 2565】Broken Audio Signal
問題
Broken Audio Signal | Aizu Online Judge
方針
- 区間を狭めていって, その区間によって結果を出力する.
- xが偶数番目のときに上界, 奇数番目のときに下界を決めることができる.
- xが連続した時はnone, 上界がないなど様々な場合分けがあってとてもつらい.
コード
#include<bits/stdc++.h> #define rep(i, n) REP(i, 0, n) #define REP(i, a, n) for(int i = a ; i < (int)n ; i++) #define MAX_V 1000000000 using namespace std; typedef long long ll; int n; string data[10000]; ll toNum(string s){ return (int)atoi(s.c_str()); } string solve(){ ll upper, lower; string prev; upper = MAX_V * 2; lower = -MAX_V * 2; prev = to_string(upper); rep(i, n){ if(data[i] == "x"){ if(prev == "x") return "none"; // xが連続 if((i+1) % 2 == 1){ // odd upper = min(upper, toNum(prev)); if(i < n-1) upper = min(upper, toNum(data[i+1])); }else{ // even lower = max(lower, toNum(prev)); if(i < n-1) lower = max(lower, toNum(data[i+1])); } }else{ // 数字のときに正しいか判別 if((i+1)%2 == 1 && prev != "x"){ if((toNum(prev)) <= toNum(data[i])) return "none"; }else if(prev != "x"){ if((toNum(prev)) >= toNum(data[i])) return "none"; } } prev = data[i]; if(upper - lower < 2) return "none"; } if(upper - lower > 2) return "ambiguous"; return to_string((upper + lower) / 2); } signed main(){ while(cin >> n, n){ rep(i, n){ cin >> data[i]; } cout << solve() << endl; } }
参考
【AOJ 2727】M and A
問題
方針
- SとTの部分文字列を交互に繋げてSを作ることができるか調べる.
- Sの部分文字列は自明にSに含まれているので, Tの部分文字列を考える.
- Tの先頭から順に探索し, 部分文字列であるかを試す. (Sの偶数番目と奇数番目をとった場合の2通り)
コード
#include<iostream> using namespace std; string S, T, s, t; bool check(){ int i; int pos = 0; if(s == "") return true; for(i = 0 ; i < (int)T.size() ; i++){ while(T[i]!=s[pos] && i < (int)T.size()) i++; if(i >= (int)T.size()) break; pos++; if(pos == (int)s.size()){ return true; } } return false; } signed main(){ bool flag = false; cin >> S >> T; s = ""; for(int i = 0 ; i < (int)S.size() ; i+=2) s += S[i]; flag |= check(); s = ""; for(int i = 1 ; i < (int)S.size() ; i+=2) s += S[i]; flag |= check(); if(flag) cout << "Yes" << endl; else cout << "No" << endl; }
【AOJ 1232】Calling Extraterrestrial Intelligence Again
問題
Calling Extraterrestrial Intelligence Again | Aizu Online Judge
方針
コード
#include <bits/stdc++.h> #define rep(i, n) REP(i, 0, n) #define REP(i, a, n) for(int i = a ; i < (int)n ; i++) using namespace std; #define MAX_M 100000 bool prime[MAX_M+1]; signed main(){ int m, a, b; rep(i, MAX_M+2){ prime[i] = true; } prime[0] = prime[1] = false; REP(i, 2, sqrt(MAX_M+2)){ if(prime[i]){ for(int j = i * 2 ; j <= MAX_M ; j+=i){ prime[j] = false; } } } while(cin >> m >> a >> b, m || a || b){ int ans_p, ans_q, ans_pq = -1; for(int p = 2 ; p <= m ; p++){ if(!prime[p]) continue; for(int q = 2 ; q <= m/p ; q++){ if(!prime[q]) continue; if(ans_pq < p * q && p * q <= m && (double)a/b <= (double)p/q && (double)p/q <= 1.0){ ans_pq = p*q; ans_p = p; ans_q = q; } } } cout << ans_p << " " << ans_q << endl; } }
【AOJ 1241】Lagrange's Four-Square Theorem
問題
Lagrange's Four-Square Theorem | Aizu Online Judge
方針
- 全部探索する.
コード
#include <iostream> using namespace std; signed main(){ int n; while(cin >> n, n){ int cnt = 0; for(int i = 1 ; i * i <= n ; i++){ if(i*i == n) cnt++; for(int j = i ; j * j <= n ; j++){ if(i*i + j*j == n) cnt++; for(int k = j ; k * k <= n ; k++){ if(i*i + j*j + k*k == n) cnt++; for(int l = k ; l * l <= n ; l++){ if(i*i + j*j + k*k + l*l == n) cnt++; } } } } cout << cnt << endl; } }
【AOJ 2300】Calendar Colors
問題
Calender Colors | Aizu Online Judge
方針
- N個のLABカラーが与えられる.
- そこからM個取り出し, 要素それぞれの差の二乗の和を求める.
- その和の最大値が答え.
- であることから全探索しても良さそう.
- M個取り出すときにbitを使うと便利っぽい.
コード
#include <iostream> #include <vector> #include <cmath> #include <cstdio> #include <algorithm> using namespace std; #define rep(i,n) REP(i,0,n) #define REP(i,a,n) for(int i = a ; i < (int)n ; i++) struct LAB{ double l, a, b; LAB(double ln, double an, double bn){ l = ln; a = an; b = bn; } }; int main(){ int n, m; double l, a, b; vector<LAB> v; scanf("%d %d", &n, &m); rep(i, n){ scanf("%lf %lf %lf", &l, &a, &b); v.push_back(LAB(l,a,b)); } double ans = -1; rep(i, (1<<n)){ vector<LAB> elem; rep(j, n){ if(i & (1 << j)){ elem.push_back(v[j]); } } if((int)elem.size() != m) continue; double tmp = 0; rep(i, m-1){ REP(j, i+1, m){ tmp += (pow(elem[i].l-elem[j].l, 2) + pow(elem[i].a-elem[j].a, 2) + pow(elem[i].b-elem[j].b, 2)); } } ans = max(ans, tmp); } printf("%.8f\n", ans); }