文系プログラマーのプログラミング備忘録

Java、競プロ、数学などについて書いてます

When I hit my pocket... [みんなのプロコン2019 予選 C]

atcoder.jp


①最初、1枚のビスケットと0円を持っている。
②以下の操作を好きな順にk回おこなったときの、ビスケットの最大値はいくつか。
 操作1:ビスケットを1枚得る
 操作2:a枚のビスケットを1円に変える
 操作3:1円をb枚のビスケットに変える


b-a<=2のときに操作2と操作3をおこなうと、ビスケットの枚数は減るか、回数を2回使うにもかかわらず1もしくは2増えるだけ(操作1のほうが得もしくは同等)なので、操作1のみをおこないます。このときの枚数の最大値は1+kです。


b-a>2の場合について考えます。


操作2と操作3は「b-a枚のビスケットを得て、回数を2回分消費する。ただし、ビスケットの枚数がa以上の場合にのみ実行できる」と置き換えることができます。まず、ビスケットの枚数がa枚になるまで、操作1をa-1回繰り返します。kからa-1を引きます。次に (k/2)*(b-a) の計算をおこない、結果をビスケットの枚数に加算します。残り回数をk%2とします。最後に余った残り回数で操作1をk回おこなって、kをビスケットの枚数に加算して終了です。

//yahoo-procon2019qual-c
 
import java.util.*;
 
class Main {
	static Scanner sc = new Scanner(System.in);
	public static void main(String[] args) {
 
		long k = sc.nextLong();
		int a = sc.nextInt();
		int b = sc.nextInt();
 
		if (b-a <= 2) System.out.println(1+k);
		else {
			long bisket = 1;
			
			//ビスケットがa枚になるまで操作1を繰り返す
			bisket += a-1;
			k -= a-1;
 
			//残りの操作回数で、操作2+操作3を(k/2)回繰り返す
			bisket += k/2*(b-a);
			k = k%2;
 
			//余った操作回数で、操作1をおこなう
			bisket += k;
 
			System.out.println(bisket);
		}
		
	}
}


問題には関係ありませんが、ビスケットの綴りはbiscuitらしいです。