imomoの勉強記録

主に勉強の記録などを残していきます

ABC184に参加しました

AtCoderのコンテストに参加した際の結果と考え方、反省点などを書いていきます。
コンテストページはこちら

解いた/挑んだ問題

A問題

問題の概要

a,b,c,dが与えられる
ad - bcを求めよ

制約
  • -100 \leq a,b,c,d \leq 100
どのように考えたか
結果

一発AC
・提出ししたコード

#include<bits/stdc++.h>
#include<atcoder/all>

#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
#define REP(i, n) for (long long i = 1; i <= (long long)(n); i++)
#define FOR(i,x,n,r) for(long long i = x; i< (long long)(n); i+=r)
#define afor(a,t) for(auto a:t)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using namespace std;
using namespace atcoder;
using ll = long long;
using pi = pair<int, int>;
ll pows(ll x, ll n) {ll ret = 1;while (n > 0) {if (n & 1) ret *= x;x *= x;n >>= 1;}return ret;}

int main() {
	int a,b,c,d;
	cin >>a >> b >> c >> d;
	cout << a * d - c * b << endl;
	return 0;
}

行列と問題文には書いてあったので怖かったが求め方が書いてあったので素直に実装した

ACまでの時間

ACしたのはコンテスト開始から1分後です。

f:id:iiiimmmmo:20201122233243p:plain
ABC184_A

B問題

問題の概要

N問あるクイズに挑戦した結果が文字列Sで与えられる
文字列の左からi文字目が o のとき、 i問目が正解、 x の時不正解を示す
最初の得点がX点でクイズに正解すると1点増え、不正解だと1点減るが、0点の時のみ不正解でも点数は減らない
クイズの結果、何点だったか答えよ

制約
  • 1 \leq N \leq 2 × 10^5
  • 0 \leq X \leq 2 × 10^5
  • Sはo x からなる長さNの文字列
どのように考えたか

持ち点が0点の時を除いてクイズの結果に応じて点数を足したり引いたりしていった

結果

一発AC
提出したコード

#include<bits/stdc++.h>
#include<atcoder/all>

#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
#define REP(i, n) for (long long i = 1; i <= (long long)(n); i++)
#define FOR(i,x,n,r) for(long long i = x; i< (long long)(n); i+=r)
#define afor(a,t) for(auto a:t)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using namespace std;
using namespace atcoder;
using ll = long long;
using pi = pair<int, int>;
ll pows(ll x, ll n) {ll ret = 1;while (n > 0) {if (n & 1) ret *= x;x *= x;n >>= 1;}return ret;}

int main() {
	int n,x;
	string s;
	cin >> n >> x >> s;
	rep(i,n){
		if(s[i] == 'o')x++;
		else{
			if(x)x--;
		}
	}
	cout << x << endl;
	return 0;
}

0点の時のみ注意が必要で、オーバーフローの可能性もなかったので安心して出せた

ACまでの時間

ACしたのはコンテスト開始から3分後です。

f:id:iiiimmmmo:20201122233959p:plain
ABC184_B

C問題

問題の概要

A(r_1,c_1),点B(r_2,c_2)が与えられる
点Aにあるコマを置き、そのコマは1回で以下の動作が可能である

  • 将棋の角の動き(斜め4方向に好きなだけ移動)
  • 今いるマスから、自由に3マスまで移動

点Aから点Bまで移動するのに必要な最小の移動回数を求めよ

制約
  • 1 \leq r_1,c_1,r_2,c_2 \leq 10^9
  • 入力はすべて整数
どのように考えたか

まず、斜めに好きなだけ移動できるので、3回移動すれば最低限着きそうってことに気づく
点A,Bの座標の和の偶奇が等しければ斜め移動だけで到達可能だが、等しくなければ偶奇を等しくするために移動が必要

1回で行けるかどうかは、

  • x座標の変化量の絶対値+y座標の変化量の絶対値が3以下の場合(3マス移動して辿り着くことができる)
  • 点A,B座標の和、もしくは差が等しい場合(斜め移動が可能)

2回で行けるかどうかは、
前提条件として、1回で到達できる条件を満たしておらず

  • 点A,Bの座標の和の偶奇が等しい(2回斜め移動で到達可能)
  • 点A,Bの座標の和の偶奇が等しくないが、3マス移動で斜め移動ができる場所にたどり着ける

それ以外は3回移動
(追記)アフターコンテストケースで嘘解法と分かりましたが、コンテスト中のコードを載せる場所なので、訂正は行いません

結果

2回目でAC
提出したコード

#include<bits/stdc++.h>
#include<atcoder/all>

#define rep(i, n) for (long long i = 0; i < (long long)(n); i++)
#define REP(i, n) for (long long i = 1; i <= (long long)(n); i++)
#define FOR(i,x,n,r) for(long long i = x; i< (long long)(n); i+=r)
#define afor(a,t) for(auto a:t)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using namespace std;
using namespace atcoder;
using ll = long long;
using pi = pair<int, int>;
ll pows(ll x, ll n) {ll ret = 1;while (n > 0) {if (n & 1) ret *= x;x *= x;n >>= 1;}return ret;}

int main() {
	ll x1,y1,x2,y2;
	cin >> x1 >> y1 >> x2 >> y2;
	if(x1 == x2 && y1 == y2){cout << 0 << endl;return 0;}
	ll a = x1 + y1,b=x2+y2;
	ll c = x1 - y1,d=x2-y2;
	if((abs(x2 - x1) + abs(y2 -y1)) <= 3){cout << 1 << endl;return 0;}
	if(a%2==b%2){
		if(a ==b || c == d)cout <<1 << endl;
		else cout << 2 << endl;
	}else{
		if(abs(a-b) <= 3 || abs(c-d) <= 3)cout << 2 << endl;
		else cout << 3 << endl;
	}
	return 0;
}

紙に書きながら場合分けして答えにたどり着いてよかった

ACまでの時間

ACしたのはコンテスト開始から60分後。

f:id:iiiimmmmo:20201123001048p:plain
ABC184_C

コンテスト結果

ABCの3完でした。
今回はC問題が難しかったと感じましたがC問題まで解けて良かったです!

f:id:iiiimmmmo:20201123001255p:plain
ABC184

パフォーマンス、レーティング変動

今回のパフォーマンスは872、前回より500も上がりました
レーティングはそれに伴い+29の637となりました。

f:id:iiiimmmmo:20201123001525p:plain
コンテスト成績表
f:id:iiiimmmmo:20201123001541p:plain
ABC184を終えた時点でのレーティング

反省点

今回はC問題の性質に気づくことこそできましたが、コンテスト開始から40分ほどたってからでした
問題の性質に早く気づき、素早く解けるように頑張っていきたいです