Editorial for 第2回卬高杯 A問題 - Shizukou Days
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
概略
- この問題は、複数回の条件分岐(if文)によって解くことができます。
- 最大14回のif文を書くことで解けますが、それより簡潔に書く方法もあるため、そちらもあわせて紹介します(下記参照)。
条件分岐の方法、主なパターン
なぜ工夫して書きたがるのか
競技プログラミングの世界では、基本的に1つの大会に数個の問題しか出ません。部分点がある場合もありますが、そうでない問題は完答しなければ0点です。
同じ点数になると、「どちらがより速く問題を解き終えたか」の勝負になり、
これだけで順位が大きく変わってしまいます(特に簡単な問題が多いほど、その傾向は顕著に現れる)。
また、全ての問題には「時間制限」が存在し、決められた時間以内にプログラムが答えを出せなければ不正解(TLE=時間制限超過)になってしまいます。
簡潔に書くことで、時間制限内に収める事ができます。
これらが主な理由です。
※あとは入力ミスを減らすことができるなど。コードをできるだけ短く書きたがる
1. それぞれの日ごと対応させてしまう
実装例1(C++20):
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
string t;
cin >> s >> t;
if(t=="A"){
if(s=="Sunday"){
cout << "No" << endl;
}
else if(s=="Monday"){
cout << "Yes" << endl;
}
else if(s=="Tuesday"){
cout << "Yes" << endl;
}
else if(s=="Wednesday"){
cout << "Yes" << endl;
}
else if(s=="Thursday"){
cout << "Yes" << endl;
}
else if(s=="Friday"){
cout << "Yes" << endl;
}
else if(s=="Saturday"){
cout << "Yes" << endl;
}
}
else if(t=="B"){
if(s=="Sunday"){
cout << "No" << endl;
}
else if(s=="Monday"){
cout << "Yes" << endl;
}
else if(s=="Tuesday"){
cout << "Yes" << endl;
}
else if(s=="Wednesday"){
cout << "Yes" << endl;
}
else if(s=="Thursday"){
cout << "Yes" << endl;
}
else if(s=="Friday"){
cout << "Yes" << endl;
}
else if(s=="Saturday"){
cout << "No" << endl;
}
}
}
すごく…(コード長が)大きいです…
これでは書き終えるまでに時間がかかってしまいます。1秒を争う中でこんなコードを書いていられません。
何かもっといい方法はないでしょうか。2. あるものに注目する
ここまでで、何か感じたことはありませんか?
…そうです。No
です。
No
となる日は日曜日とB週日課の土曜日だけ。
他は全部Yes
になるのだから、この3日に注目して条件分岐をしてみましょう。
実装例2(C++20):
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
string t;
cin >> s >> t;
if(s=="Sunday"){
cout << "No" << endl;
}
else if(s=="Saturday"){
if(t=="B"){
cout << "No" << endl;
}
else{
cout << "Yes" << endl;
}
}
else{
cout << "Yes" << endl;
}
}
これをノーヒントで書けたならば、あなたは競技プログラミングにかなり向いていると思います。きっと。最後に、もう少しだけ短くしてみましょう。
3. さらに短く書く方法
- 変数の宣言において、同じ型(文字列が入るのか、数値が入るのかを決める定義的なもの)であれば、
,
を使って複数の変数を宣言できてしまいます。 &&
や||
を用いて、複数の条件式を1つにまとめていきます。例えば、if(A&&B){(実行)}
、if(C||D){(実行)}
というコードを書いた時、それぞれ「AかつB ならば(実行)」「CまたはD ならば(実行)」という意味になります。- if文は、その中の実行内容が1つだけ(セミコロン1つだけ)の場合は、
{}
を省略して書く事ができてしまいます。
実装例3(C++20):
#include <bits/stdc++.h>
using namespace std;
int main(){
string s, t;
cin >> s >> t;
if((s=="Sunday") || (s=="Saturday" && t=="B")) cout << "No";
else cout << "Yes";
}
最終的にコードを10行以内で書き終える事ができたので、私の解説はここで終わりにしようと思います。補足
- 実際には、B週日課にもかかわらず土曜日も授業があったり、A週日課なのに土曜日に授業がなかったりします。予定はしっかり確認しておきましょう。
Comments