De.HP

おバイクお出かけお写真とお釣りとおプログラミングとお雑記です。

AtCoder Beginner Contest 169 (ABC169) ふりかえり

二週間ぶりのABCでした。今のレートが300ちょいくらいなので、後数回、うまくいけば今回で茶色になってやろうと闘志を燃やしていたのですが、結果はB問題で"WA"を連発し、C問題も解けず、2完に終わりました。

結構 "WA" を出しやすいような問題が多く、出題者への苛つきを感じずにはいられませんでした。一方で、オーバーフローや浮動小数点型の誤差など、プログラミング言語そのものをしっかりと理解していればスラスラ解けたであろう問題だったので、とても勉強になったとも言えます。

A - Multiplication 1

atcoder.jp

ただの掛け算だったのでイージーでした。

#include<bits/stdc++.h>
using namespace std;

int main(){

  int A, B;
  cin >> A >> B;
  
  cout << A * B << endl;
  return 0;
}

B - Multiplication 2

atcoder.jp

最初にゼロ判定を行う。ゼロが出たらゼロを出力して終了。
次に、順々にかけていって10^18を超えたら - 1、オーバーフローしてしまうので、割り算の形にしておかないといけない。

#include
using namespace std;

int main(){

  long long N, i, a;
  bool flag = false;
  cin >> N;
  vector<long long> A(N);
  
  for (i = 0; i < N; i++){
    
    cin >> A.at(i);
    
    if(A.at(i) == 0){
      cout << 0 << endl;
      return 0;
    }
  }
  
  long long Asum = A.at(0);
  
  for (i = 1; i < N; i++){
    
    if(Asum > 1000000000000000000ll/A.at(i)){
      cout << -1 << endl;
      return 0;
    }
    Asum = Asum * A.at(i);
  }
  
  cout << Asum << endl;
  return 0;
}

C - Multiplication 3

atcoder.jp

できなかった。めちゃくちゃ悔しい。少数の部分で誤差が出ているので、100をかけて整数同士で計算してから、100で割るという戦略をとった。これが大間違いで、100をかけて整数型にするときにも、誤差の影響が出る場合があるようです。文字列として扱った後に計算するか、微小な数字を足してやることで解決できるそうです(下記リンク参照)。知らなかった。。。


drken1215.hatenablog.com

まとめ

非常に悔しい。レートは変動無しでした。次こそはっ!