先週にに引き続きAtCoderをやっていこうと思います
先週の様子はこちら
勉強ペースが亀のように遅いので、APG4bが終わるのはいったいいつになるんだろうか…
少なくとも7月中旬には終わらせておきたいなあとは思っている
1週間毎日振れた感想としては、講義でCをやっていたときよりは楽しくできているし、(一応)理解も進んでいるな、ということ
パズルとかクイズみたいな感覚で問題を解けているので、意味も分からず書いていた講義の頃よりは充実感がある
1日目(1.11~)
1.11のコンテスト問題をB - Addition and Multiplicationから解いた
中でもB - Palindromic Numbersはなかなかてこずった
自分は以前学んだ%10を使って、桁を落としていく手法を使って、各桁の数を取得し、それらを比較することで、探索する方針にした
#include<iostream>
using namespace std;
int main(){
int A, B;
cin >> A >> B;
int a, b, c, d, e, x = 0;
for(int i = A; i < B+1; i++){
a = i % 10;
b = (i/10) % 10;
c = (i/100) % 10;
d = (i/1000) % 10;
e = (i/10000) % 10;
if(a == e && b == d){
x += 1;
}
}
cout << x << endl;
}
i をそのまま変数として計算させるのは、我ながらいいアイデアだったとは思うんだけど、桁を落としていくところができなかったので、またしてもパワープレイで対処することに…
今回、いいなあと思ったコードはこちらのもの
#include <bits/stdc++.h>
using namespace std;
int main() {
int A,B,a,b,c,N,S;
cin >> A >> B;
S=0;
for(int i=1;i< 10; i++){
a =i;
for(int j=0;j<10; j++){
b = j;
for(int k=0;k<10;k++){
c = k;
N =10000*a+1000*b+100*c+10*b+1*a;
if(A<=N && N <=B){
S++;}
}
}
}
cout << S << endl;
}
自分は数字を1ずつ増やして判断して、を繰り返してカウントアップしていく感じだったけど
この人は数字を範囲内でがちゃがちゃっと回して、当てはまるものを探す感じのイメージのものだと思う
大枠から絞り込んでいくイメージは大事だなあと思った
2日目
なし
3日目
なし
4日目、5日目
B - Shift only で一生躓いている
無限ループになってるっぽいんだけど、どこが間違っているかわからない
#include<iostream>
using namespace std;
int main(){
int N;
cin >> N;
int ans = 0;
int C = 0;
for(int i =0; i < N; i++){
int A;
cin >> A;
if(ans >= C){
ans = C;
C = 0;
}
else{
C = 0;
}
while(A > 1){
if(A % 2 == 0){
A /= 2;
C++;
}
}
}
cout << ans << endl;
}
イメージとしてはデータ数が与えられて、その数を上限としてループを行う
入力データAを拾って、何回2で割れるかをCで記録し、それをansに入れ込む
2回目以降は同じ作業を行って、ansとCを比較し小さいほうの数を採用し、Cには0を入れて初期化
・・・というつもりだったのだけど、無限ループしているようなので、それ以前の問題になっており、どこが原因で無限ループしているのかわからない
無限ループを自分で見つけるのも訓練だと思うので、しばらく先に進めなさそう、南無
6日目(1.11~1.12(A-添え字))
#include<iostream>
using namespace std;
int main(){
int N;
cin >> N;
int ans = 0;
int C = 0;
for(int i =0; i < N; i++){
int A;
cin >> A;
while(A % 2 == 0){
A /= 2;
C++;
}
if(i == 0){
ans = C;
C = 0;
}
else{
if(ans >= C && C != 0){
ans = C;
C = 0;
}
else{
C = 0;
}
}
}
cout << ans << endl;
}
こう書き直したら、なぜかうまくいった
変更点はiで処理の場合分けをしたこと
最初はansにそのままCを入れて、ループ2回目から比較をするようにした
Cはその都度リセットする方針もうまくいっていた
while(A > 1){
if(A % 2 == 0){
A /= 2;
C++;
}
}
状況証拠的に、この部分の記述が間違っていてエラーを吐いていたっぽい
i, A, C, ansを毎回出力しながらループをさせていたんだけど、偶数のときはうまく動いて、素因数に奇数を含むときにエラーコード9が出ていたので、奇数の場合の場合分けみたいなのが間違っていたんだと思う
計算自体はやってはいるけど、時間がかかりすぎている、という感じっぽく見えたから、無限ループとはまた違ったかも
Aはint型だから、A=10とかだと、A = 2.5→2, A = 1となってwhileの条件に当てはまらない状態が出てしまってエラーが出てたのかなと思った
自分の意図としては、2で割って1余ったら終わりで、その下限が1という意図で書いてたんだけど、この辺の認識があいまいだったかなという感じ
最初の書き方をするなら、Aの偶奇で場合分けをしないといけないけど、それをやるくらいなら、条件をうまく書き換えるほうが早いな、みたいな反省
EX12足したり引いたりで感心したコード
#include <bits/stdc++.h>
using namespace std;
int main() {
string S;
cin >> S;
int a = 1;
for(int i = 0; i < S.size()-1; i=i+2) {
if(S.at(i+1) == '+'){
a++;
}
else if(S.at(i+1) == '-') {
a--;
}
}
cout << a << endl;
自分はi番目の文字が+or-で一致するか判定して、個数を数えて、その差を取って1に足すという計算を取っていたけど、 iを2つずつ飛ばすほうが確かにそれがスマートかも
A - AtCoder *** Contestなんだけど
getline(cin, x)で行を取得して、その行の何文字目を表示ってどうしたらいいんだろう
と書いて色々、修正してたら数を数え間違ってた
AtCoderの後ろにスペースが入ってるのを忘れてて、x.(7)でなんでいけないんだ…って悩んでたけど、x.at(8)で普通にできたわ