怠惰の累積和

技術/競プロ/怪文書/虚無

JOI 2019/2020 一次予選 (第2回:10月27日(日))

はじめに

お疲れさまでした。6:08で全完でした。以下いつものように解法をば...



A - 試験 (Exam)

問題概要

 3回分の試験の得点が与えられる。成績は3つの内大きい方から2つの和で決まるから、大きい2つの点数を足した値を出力せよ。

問題URL

解法

 愚直にif文を書いたり任意の2得点の和の最大値を出力したりしても良いが多分3つの総和から最も小さい得点を引くのが最も楽。所要時間27秒。(以下ソースコードはmain関数のみ)

int main() {
	int a, b, c;
	cin >> a >> b >> c;
	cout << a + b + c - min({ a,b,c }) << endl;
}



B - 文字列の反転 (Inversion of a String)

問題概要

 文字列SA文字目からB文字目までを反転させるとどのようになるか。

問題URL

解法

 適当にやる。具体的には前から出力する区間2つと反転させる区間との3つに分けて出力してやる。添え字に注意する。所要時間2分39秒。

int main() {
	int a, b, c;
	cin >> a >> b >> c;
	--b; --c;
	string h;
	cin >> h;
	for (int i = 0; i < b; ++i) { cout << h[i]; }
	for (int i = c; i >= b; --i) { cout << h[i]; }
	for (int i = c + 1; i < a; ++i) { cout << h[i]; }
	cout << endl;
}



C - 最頻値 (Mode)

問題概要

 要素数Nの数列Aから数列Bを新たに生成する(生成規則書くの面倒すぎるので割愛)。Bの最大値は幾らか。

問題URL

解法

 Aの要素を順に見て行き、各要素がどのくらい登場したかを記録しておく。後はその中での最大値を取ればよい。所要時間3分2秒(焦ったせいで変数名が(いつもだけど特に)適当になってしまった...)

int a, b, k[105], ans[105], aa;
int main() {
	cin >> a >> b;
	for (int i = 0; i < a; ++i) {
		cin >> k[i];
		++ans[k[i] - 1];
	}
 
	for (int i = 0; i < b; ++i) {
		aa = max(aa, ans[i]);
	}
	cout << aa << endl;
}