No.632 穴埋め門松列
はじめに
競技プログラミング、yukicoder
No.632 穴埋め門松列
言語はC#
何かあればTwitter→@pirorirori_n712まで
問題
入力:c1 c2 c3
3つの文字は,'2'か,'3','?'のいずれか
(文字の重複はない)
出力:「1」か「4」か「14」
「?」を「1」か「4」どちらで置き換えれば入力を門松列にできるかを出力する
ただし、どちらでもいい場合は「14」を出力する
☆門松列とは?
3つの自然数から成る数列v=(a1,a2,a3)が次の条件を満たす列
1 a1,a2,a3は全て異なる
2 3つの要素のうちa2が最も大きい,あるいは最も小さい
解き方
門松列は真ん中の文字が
他の2文字よりも「小さい」か「大きい」列なので
真ん中の文字に注目すると短く解ける
入力が3文字と決まっていて「2、3、?」が重複なしで与えられるので
次のように真ん中の文字で場合分けができる
①真ん中の文字が「2」の場合
残りの2文字は「3」と「?」
このとき「2」は「3」よりも小さいので、出来上がる門松列は2が一番小さくなる
(考えられる文字列を書き出すと「3 2 ?」「? 2 3」の2パターン)
3文字の中で真ん中の「2」が一番小さくなければいけないので、
「1」と「4」のうち、「2」よりも大きい「4」が答えとなる
(先ほどのパターンに入れてみると「3 2 4」「4 2 3」となり、門松列になることが分かる)
②真ん中の文字が「3」の場合
残りの2文字は「2」と「?」
このとき「3」は「2」よりも大きいので、出来上がる門松列は3が一番大きくなる
(考えられる文字列を書き出すと「2 3 ?」「? 3 2」の2パターン)
3文字の中で真ん中の「3」が一番大きくなければいけないので、
「1」と「4」のうち、「3」よりも小さい「1」が答えとなる
(先ほどのパターンに入れてみると「2 3 1」「1 3 2」となり、門松列になることが分かる)
③真ん中の文字が「?」の場合
残りの2文字は「2」と「3」
試しに端が「2」と「3」の列を書き出してみると
「2 ? 3」「3 ? 2」の2つであることが分かる
門松列は真ん中が他の2文字よりも「小さい」か「大きい」列である
ここから真ん中に入れる文字を考えると
「1」は「2」と「3」どちらの数字よりも小さい
よって「1」を「?」に置き換えると真ん中が一番小さい門松列が出来上がる
したがって、「1」は正解
次に「4」は「2」と「3」どちらの数字よりも大きい
よって「4」を「?」に置き換えると真ん中が一番大きい門松列が出来上がる
したがって、「4」も正解なので「14」を出力すればいいことが分かる
①ifで場合分け
②条件演算子で場合分け
①ifで場合分け
コード例
using System; class No632{ static void Main(string[] args){ //入力された文字列を「' '」で区切って配列にし、変数strに格納 var str=Console.ReadLine().Split(' '); //出力を書く部分を一つにしたい(Console.WriteLine()を一回しか書きたくない)ので //答えを入れる変数を用意し、(適当に0で初期化) //ここに答えを入れ最後に出力できるようにする var answer=0; //真ん中の文字は2番目の文字なのでstr[1] //真ん中の文字が2のとき if(str[1]=="2"){ //2が一番小さくなるようにしたいので答えは4 answer=4; }//真ん中の文字が3のとき else if(str[1]=="3"){ //3が一番大きくなるようにしたいので答えは1 answer=1; }//真ん中が「2」でも「3」でもないとき、すなわち「?」のとき else{ //「1」でも「4」でも門松列になるので答えは14 answer=14; } //最後に答えを出力 Console.WriteLine(answer); } }
先にanswerに14を入れて初期化しておくと最後のelseのブロックを省略できる
using System; class No632{ static void Main(string[] args){ //入力された文字列を「' '」で区切って配列にし、変数strに格納 var str=Console.ReadLine().Split(' '); //出力を書く部分を一つにしたい(Console.WriteLine()を一回しか書きたくない)ので //答えを入れる変数を用意し //以下に続くif分のブロックのどちらの条件(真ん中が「2」か「3」)にも該当しなければ //14になるように(真ん中が「?」のときの解答)しておく var answer=14; //真ん中の文字は2番目の文字なのでstr[1] //真ん中の文字が2のとき if(str[1]=="2"){ //2が一番小さくなるようにしたいので答えは4 answer=4; }//真ん中の文字が3のとき else if(str[1]=="3"){ //3が一番大きくなるようにしたいので答えは1 answer=1; } //最後に答えを出力 Console.WriteLine(answer); } }
②条件演算子で場合分け
if文で場合分けをせずに、条件演算子で一行にまとめます
コード例
using System; class No632{ static void Main(string[] args){ //入力された文字列を「' '」で区切って配列にし、変数strに格納 var str=Console.ReadLine().Split(' '); //answerという変数を用意し答えを入れる //真ん中の文字が2のとき4,真ん中の文字が3のとき1、真ん中の文字が「2」でも「3」でもないとき(すなわち「?」のとき)14 var answer=(str[1]=="2")?4:(str[1]=="3")?1:14; //最後に答えを出力 Console.WriteLine(answer); } }