kmjp's blog

競技プログラミング参加記です

AtCoder ARC #023 : A - 経過日数、B - 謎の人物X

少し遅れて参加したけど、あまり遅刻の影響がない順位だった。
http://arc023.contest.atcoder.jp/tasks/arc023_1
http://arc023.contest.atcoder.jp/tasks/arc023_2

A - 経過日数

西暦1年1月1日とy年m月d日の間の日数を求める公式が与えられる。
これを用いて、与えられた日付と2014/5/17の間の日数を求めよ。

式にあてはめて計算するだけ。

void solve() {
	int f,i,j,k,l,x,y;
	
	int Y,M,D;
	cin>>Y>>M>>D;
	if(M==1 || M==2) Y--,M+=12;
	x=365*Y+(Y/4)-(Y/100)+(Y/400)+(306*(M+1))/10+D-429;
	
	Y=2014;M=5;D=17;
	y=365*Y+(Y/4)-(Y/100)+(Y/400)+(306*(M+1))/10+D-429;
	cout << y-x << endl;
}

B - 謎の人物X

RxCの2次元グリッドにスコアが書かれている。
左上のマスから、隣接マスをD回移動して到達できるマスの最大スコアを求めよ。

各マスに移動できる条件は:

  • そのマスと左上マスのマンハッタン距離がD以上かつ
  • そのマスと左上マスのマンハッタン距離とDの偶奇が一致すること

である。全マスを列挙し、移動条件を満たすマスの最大スコアを求めればよい。

int R,C,D;
int A[2001][2001];

void solve() {
	int f,i,j,k,l,x,y;
	cin>>R>>C>>D;
	FOR(y,R) FOR(x,C) cin>>A[y][x];
	int ma=0;
	FOR(y,R) FOR(x,C) {
		if(y+x>D) continue;
		if((D-y-x)%2) continue;
		ma=max(ma,A[y][x]);
	}
	cout << ma << endl;
}

まとめ

Aの公式は普通に覚えておいて役に立ちそうだね。