AtCoder振り返りその2(AtCoder Beginner Contest 306)
まえがき
競技プログラミング振り返り二回目となります。
今回解けたのはA,B,C問のみのため以下はその内容の振り返りとなります。
A問(A - Echo)
問題はこちら→A - Echo
A問提出コード
#include<stdio.h> int main() { int n; char s[51]; scanf("%d", &n); scanf("%s", s); for (int i = 0; i < n; i++) { printf("%c%c", s[i], s[i]); } return 0; }
for文で2文字ずつ出しているだけですね。
これだけじゃちょっとつまらなかったので別のコードも書いてみました。
A問別コード
#include<stdio.h> int main() { int n; char s[101] = { 0 }; scanf("%d", &n); for (size_t i = 0; i < n * 2; i++) { scanf(" %c", &s[i]); i++; s[i] = s[i - 1]; } printf("%s\n", s); return 0; }
入力時に2文字ずつ配列に入れて最後に文字列を出しています。
B問(B - Base 2)
問題はこちら→B - Base 2
符号なし64bit整数を2進数で入力して、10進数に直す問題ですね。
B問提出コード
#include<stdio.h> #include<math.h> int main() { int num[65]; unsigned long long ans = 0; for (int i = 0; i < 64; i++) { scanf("%d", &num[i]); } for (int i = 0; i < 64; i++) { if ((int)num[i]) { ans += (unsigned long long)pow(2, (double)i); } } printf("%llu\n", ans); return 0; }
入力後に一文字ずつ見ていき、for文で桁数に合わせて1であれば足し算をしています。
B問提出コード(改善)
#include<stdio.h> #include<math.h> int main() { int num; unsigned long long ans = 0; for (int i = 0; i < 64; i++) { scanf("%d", &num); if (num) { ans += (unsigned long long)pow(2,(double)i); } } printf("%llu\n", ans); return 0; }
for文を1つにして入力を保持しない形に直しました。
B問別回答
#include<stdio.h> int main() { unsigned long long ans = 0, num; for (int i = 0; i < 64; i++) { scanf("%llu", &num); if (num) { ans += num << i; } } printf("%llu\n", ans); return 0; }
シフト演算子を使ってみました、あまり使う機会が少ないのでこのような問題はありがたいですね。
C問(C - Centers)
問題はこちら→C - Centers
1からNまでの整数が3個づつ、長さ3Nの数列にランダム並びで入っており。1からNまでの整数を2回目に出てくる並びで出力するものです。
C問提出コード
#include<stdio.h> #include<math.h> int main() { static int num[1500000]; static int num2[500000] ={ 0 }; int n; scanf("%d", &n); for (int i = 0; i < n * 3; i++) { scanf("%d", &num[i]); } for (int i = 0; i <= n * 3; i++) { num2[num[i]]++; if (num2[num[i]]== 2)printf("%d ", num[i]); } return 0; }
整数を受け取ったあとに別のfor文で1文字ずつ見ていき受け取った整数の配列num2に1足して2の時にその文字を出力します。
提出したコード内容はほぼ問題ないですが、確保する配列が過剰になってB問で使用した#include
またACを得られなかったコードもここで供養したいと思います。
C問提出TLEコード(誤回答)
#include<stdio.h> #include<math.h> int main() { static int num[1500000]; int n; scanf("%d", &n); for (int i = 0; i < n * 3; i++) { scanf("%d", &num[i]); } for (int i = 1; i <= n; i++) { for (int j = 0; j <= n * 3; j++) { if (num[j] == i) { num[j] = 0; break; } } for (int j = n * 3; j > 0; j--) { if (num[j] == i) { num[j] = 0; break; } } } for (int i = 0; i < n * 3; i++) { if (num[i]) { printf("%d ", num[i]); } } return 0; }
このコードでは2重for文を使用して両端から探索し1番目と3番目に出てくる数字に0を代入し、出力時に0以外を出力するものです。
このコードは時間超過のため通りませんでした。
こちらのコードでも配列数が過剰で#include
感想
今回のABCは時間内にC問まで解くことができました。
ですが残念ながらUnlatedになってしまいました。
C問では時間超過のコードを出してしまい、改善に少々時間がかかってしまい、なんとか解答を出すことができました。
ですが、これまでに書いたコードではほとんど全探索をしているため、これからは実行時間も気にして書いていきたいと思います。