ICPC 2020-A カウントダウンアップ2020 解説
問題:
https://onlinejudge.u-aizu.ac.jp/challenges/sources/ICPC/Prelim/1640?year=2020
問題の概要
0
から9
までの整数で構築された配列があります。この配列の部分列として2,0,2,0
はいくつありますか?
ただし、部分列が重なっていても別に数えます。
解法(一般論)
配列の要素を先頭から順に見ていって、そこから先の4要素が2,0,2,0
かを判定すれば良いです。
具体的には、i = 0,1,....,n-4
に対して、[i]=2, [i+1]=0, [i+2]=2, [i+3]=0
かどうかを判定します。これはfor文の中でif文を4つ書いたりして頑張ると書けます。
後述しますが、C++では事前にstring型にしてしまってから.substr()
を使う、pythonではリストのスライスを使うことで、処理を簡略化できます。
実装(C/C++)
C言語では、前述した方法をそのまま適用すれば解けます。
#include <stdio.h> int main(){ int n; while(scanf("%d", &n)){ if(n==0)break; int v[1005]; // 入力 for(int i=0;i<n;i++)scanf("%d", &v[i]); // 数える変数 int ans = 0; // 判定 for(int i=0;i<n-3;i++){ if(v[i]==2 && v[i+1]==0 && v[i+2]==2 && v[i+3]==0){ ans++; } } // 出力 printf("%d\n",ans); } }
実装(C++の別解)
別解としては、先に文字列にしてしまって、.substr(idx, len)
を使う方法があります。substr(idx, len)
は、文字列の添字idx
から、len
文字だけ切り取ります。例えば、
#include <iostream> #include <string> using namespace std; int main(){ string s = "abcde"; // 1番目の文字から2文字切り取る string sub = s.substr(1, 2); cout<<sub<<endl; // "bc"が出力される }
です。
これを使うと、以下のように書けます。
#include <iostream> #include <string> using namespace std; int main(){ int n; while(cin>>n){ if(n==0)break; int v[1005]; // 入力 for(int i=0;i<n;i++)cin>>v[i]; string s = ""; // 文字列化 for(int i=0;i<n;i++){ s += '0'+v[i]; } int ans = 0; // 判定 for(int i=0;i<n-3;i++){ // 添字iから4文字切り取る if(s.substr(i, 4) == "2020"){ ans++; } } cout<<ans<<endl; } }
判定は楽になりますが、文字列に直す処理がめんどくさいので、プラマイゼロって感じです。
実装(python)
pythonは、デフォルトで入力を文字列として受け取るので、非常に楽です。一部を切り取るのもスライス[:]
でできます。
この場合に気をつけないといけないのは,文字列には空白も含むので,切り取る長さは7文字になることです.また,for文の範囲もn
までではなく,len(文字列)
までになることに注意です.(以下のコードでは,スライスが配列外参照しないことを利用して,forの範囲は少しサボっています.)
while True: n = int(input()) if n == 0: break # 入力 s = input() ans = 0 # 判定 for i in range(len(s)): # 7文字切り取る if s[i:i+7] == "2 0 2 0": ans += 1 print(ans)
もし、整数のリストに直したとしても、スライスで一撃です。
while True: n = int(input()) if n == 0: break # 入力 v = list(map(int, input().split())) ans = 0 # 判定 for i in range(n): # 4要素切り取る if v[i:i+4] == [2,0,2,0]: ans += 1 print(ans)
A問題みたいに,特に計算量を考えなくて良い場合はpythonのがサクッと書けて良いかもしれない.