数え上げまみれでレート上がったので良し?
— ボンド@競プロ (@bond_cmprog) October 10, 2020
Bondo416さんのHHKB プログラミングコンテスト 2020での成績:618位
パフォーマンス:1692相当
レーティング:1398→1431 (+33) :)#AtCoder #HHKBプログラミングコンテスト2020 https://t.co/PkJVJdlDZa
A - Keyboard
制約全然見てなかったのでTが1文字以上だと思ってた
'a', 'b', 'c'の3通りなのでif文
提出コード
void solve(){ char S; string T; cin >> S >> T; if(S == 'Y'){ REP(i,T.size()){ if(T[i] == 'a') T[i] = 'A'; if(T[i] == 'b') T[i] = 'B'; if(T[i] == 'c') T[i] = 'C'; } cout << T << endl; } else{ cout << T << endl; } }
B - Futon
マスとマス)が '.' のとき
あるいは、マスとマス)が '.' のとき答えを1加算していけばいい
提出コード
void solve(){ int H, W; cin >> H >> W; vector<string> fi(H); REP(i,H) cin >> fi[i]; int ans = 0; REP(i,H) REP(j,W){ if(i < H-1) if(fi[i][j] == fi[i+1][j] and fi[i][j] == '.') ans++; if(j < W-1) if(fi[i][j] == fi[i][j+1] and fi[i][j] == '.') ans++; } cout << ans << endl; }
C - Neq Min
C++ならsetを使うと楽
の整数をsetに入れておく
その後をsetから消去し、setに入っている最小の整数を出力すればいい
提出コード
void solve(){ int N; cin >> N; set<int> st; REP(i,202020) st.insert(i); REP(i,N){ int m; cin >> m; st.erase(m); cout << *st.begin() << endl; } }
D - Squares
難しい
コンテスト終わり際に縦横独立でいいじゃーんになったけど間に合わず
以下解説を参考
全体の場合の数から2つの正方形が重なる場合の数を引いてあげればいい
縦横独立に考えていいので、縦(or 横)のみを考えたときに2つの正方形が重なる場合の数()の二乗を全体から引けばいい
これはAとBの置き方からAとBが重ならない場合の数()を引くと求めることが出来る
は赤と青を区別せずに考えた時、○正○正○○のように並べる場合の数となる(正は赤と青を区別しない正方形)
これは全体の個数から2個選ぶ通りとなる
実際には赤青、青赤の2通りの並び方があるので
通りとなる
よってとなり
したがってが答え
提出コード
void solve(){ ll N, A, B; cin >> N >> A >> B; if(A + B > N){ cout << 0 << endl; return; } mint ans = (N - A + 1) * (N - A + 1); ans *= (N - B + 1) * (N - B + 1); mint x4 = mint(N - A - B + 2) * mint(N - A - B + 1) / 2; mint x2 = mint(N - A + 1) * mint(N - B + 1) - x4 * mint(2); cout << ans - x2 * x2 << endl; }
E - Lamps
各マスが答えにどれだけ寄与するかを考える
照明のおけるマスの個数をとする
あるマスが光るには自分自身を含めた、その上下左右4方向で壁に当たるまでのマスの個数のどれかが光っていればいい
この個数をとすると、が全部光っていない場合以外はマスが光ることになる
よってこの場合の数はとなる
また、マスが光っているとき、残りのの照明が光っていても光っていなくても変わらないのでその分をかけ合わせたがマスの答えに寄与する回数となる
後は、照明のおける各マスの総和を求めればいい
愚直に上下左右のマスの個数を数えると間に合わないので予め累積和で求めておく
累積和を求めるパートはABCで既出
atcoder.jp
int UP[2020][2020],DOWN[2020][2020],LEFT[2020][2020],RIGHT[2020][2020]; void solve(){ int H, W; cin >> H >> W; vector<string> fi(H); ll sum = 0; REP(i,H) cin >> fi[i]; REP(i,H) REP(j,W) if(fi[i][j] == '.') sum++; REP(i,H){ int cur = 0; for(int j=0;j<W;j++){ if(fi[i][j] == '#') cur = 0; else cur++; RIGHT[i][j] = cur; } } REP(i,H){ int cur = 0; for(int j=W-1;j>=0;j--){ if(fi[i][j] == '#') cur = 0; else cur++; LEFT[i][j] = cur; } } REP(j,W){ int cur = 0; for(int i=0;i<H;i++){ if(fi[i][j] == '#') cur = 0; else cur++; UP[i][j] = cur; } } REP(j,W){ int cur = 0; for(int i=H-1;i>=0;i--){ if(fi[i][j] == '#') cur = 0; else cur++; DOWN[i][j] = cur; } } mint ans = 0; REP(i,H) REP(j,W){ if(fi[i][j] == '#') continue; ll cnt = UP[i][j] + DOWN[i][j] + LEFT[i][j] + RIGHT[i][j] - 3; ll res = sum - cnt; ans += mint(modpow(mint(2), cnt) - 1) * modpow(mint(2), res); } cout << ans << endl; }