🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

798閲覧

AtCoderのabc001_3のテストケースを通過できません

smile_20200722

総合スコア11

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2021/03/29 03:23

編集2021/03/30 01:33

AtCoderのabc001_3の問題を問いています。
以下のプログラムを提出すると、テストケースを通過できません。
入力例のものは以下の回答で通過できました。
テストケースの内容がわからないので、どこをどう修正していいのかわかりません。
お教えいただけると助かります。

問題文の貼り付けがうまくできないので、お手数ですが以下のリンクからご確認ください。

https://atcoder.jp/contests/abc001/tasks/abc001_3

該当のソースコード

C++

1 #include <bits/stdc++.h> 2 using namespace std; 3 4 float round_n(float number, double n) { 5 number = number * pow(10, n - 1); //四捨五入したい値を10の(n-1)乗倍する。 6 number = round(number); //小数点以下を四捨五入する。 7 number /= pow(10, n - 1); // 10の(n-1)乗で割る。 8 return number; 9 } 10 11 int main() { 12 float deg, dis; 13 cin >> deg >> dis; 14 deg /= 10; 15 string wind_direction; 16 if(deg >= 11.25 && deg < 33.75) { 17 wind_direction = "NNE"; 18 } else if(deg >= 33.75 && deg < 56.25) { 19 wind_direction = "NE"; 20 } else if(deg >= 56.25 && deg < 78.75) { 21 wind_direction = "ENE"; 22 } else if(deg >= 78.75 && deg < 101.25) { 23 wind_direction = "E"; 24 } else if(deg >= 101.25 && deg < 123.75) { 25 wind_direction = "ESE"; 26 } else if(deg >= 123.75 && deg < 146.25) { 27 wind_direction = "SE"; 28 } else if(deg >= 146.25 && deg < 168.75) { 29 wind_direction = "SSE"; 30 } else if(deg >= 168.75 && deg < 191.25) { 31 wind_direction = "S"; 32 } else if(deg >= 191.25 && deg < 213.75) { 33 wind_direction = "SSW"; 34 } else if(deg >= 213.75 && deg < 236.25) { 35 wind_direction = "SW"; 36 } else if(deg >= 236.25 && deg < 258.75) { 37 wind_direction = "WSW"; 38 } else if(deg >= 258.75 && deg < 281.25) { 39 wind_direction = "W"; 40 } else if(deg >= 281.25 && deg < 303.75) { 41 wind_direction = "WNW"; 42 } else if(deg >= 303.75 && deg < 326.25) { 43 wind_direction = "NW"; 44 } else if(deg >= 326.25 && deg < 348.75) { 45 wind_direction = "NNW"; 46 } else { 47 wind_direction = "N"; 48 } 49 50 float wind_speed = dis / 60; 51 // wind_speed = round(wind_speed * 100) / 100; 52 wind_speed = round_n(wind_speed, 2); 53 54 int W; 55 if(wind_speed >= 0.0 && wind_speed <= 0.2) { 56 W = 0; 57 wind_direction = "C"; 58 } else if(wind_speed >= 0.3 && wind_speed <= 1.5) { 59 W = 1; 60 } else if(wind_speed >= 1.6 && wind_speed <= 3.3) { 61 W = 2; 62 } else if(wind_speed >= 3.4 && wind_speed <= 5.4) { 63 W = 3; 64 } else if(wind_speed >= 5.5 && wind_speed <= 7.9) { 65 W = 4; 66 } else if(wind_speed >= 8.0 && wind_speed <= 10.7) { 67 W = 5; 68 } else if(wind_speed >= 10.8 && wind_speed <= 13.8) { 69 W = 6; 70 } else if(wind_speed >= 13.9 && wind_speed <= 17.1) { 71 W = 7; 72 } else if(wind_speed >= 17.2 && wind_speed <= 20.7) { 73 W = 8; 74 } else if(wind_speed >= 20.8 && wind_speed <= 24.4) { 75 W = 9; 76 } else if(wind_speed >= 24.5 && wind_speed <= 28.4) { 77 W = 10; 78 } else if(wind_speed >= 28.5 && wind_speed <= 32.6) { 79 W = 11; 80 } else if(wind_speed >= 32.7) { 81 W = 12; 82 } 83 cout << wind_direction << ' ' << W << endl; 84 return 0; 85 }

kazuma-sさんのアドバイスにより書き直したソースコード

c++

1#include <bits/stdc++.h> 2using namespace std; 3 4int main() { 5 vector<int> deg_table = {1125, 3375, 5625, 7875, 10125, 12375, 6 14625, 16875, 19125, 21375, 23625, 25875, 7 28125, 30375, 32625, 34875}; 8 9 vector<string> dir_name = {"N", "NNE", "NE", "ENE", "E", "ESE", 10 "SE", "SSE", "S", "SSW", "SW", "WSW", 11 "W", "WNW", "NW", "NNW", "C"}; 12 13 vector<int> dis_table = {int(0.25 * 60), int(1.55 * 60), int(3.35 * 60), 14 int(5.45 * 60), int(7.95 * 60), int(10.75 * 60), 15 int(13.85 * 60), int(17.15 * 60), int(20.75 * 60), 16 int(24.45 * 60), int(28.45 * 60), int(32.65 * 60), 17 int(32.75 * 60)}; 18 19 int deg, dis; 20 cin >> deg >> dis; 21 deg *= 10; 22 23 int i = 0; 24 while(i < 16 && deg >= deg_table.at(i)) { 25 i++; 26 } 27 int j = 0; 28 while(j < 12 && dis >= dis_table.at(j)) { 29 j++; 30 } 31 if(j == 0) { 32 i = 17; 33 } 34 cout << dir_name.at(i) << ' ' << j << endl; 35 36 return 0; 37}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

1T2R3M4

2021/03/29 04:03

>特別な向きであるcとします。 問題にはcってあるけど。関係ありますかね。
smile_20200722

2021/03/29 08:09

1T2R3M4さん、返信ありがとうございます。 cを小文字にということでしょうか? 試しにやってみましたが、通過できないテストケースが増えてしまいました。 他に何かお気づきの点がありましたらお願いいたします。
guest

回答2

0

ベストアンサー

浮動小数点数を扱うから誤差が問題になるのです。
入力が整数で与えられるのなら、全部整数で計算すればよいでしょう。

一例を挙げますが、もちろんこの通りにコーディングする必要はありません。

C++

1#include <iostream> 2using namespace std; 3 4int deg_table[] = { 5 1125, 3375, 5625, 7875, 10125, 12375, 14625, 16875, 6 19125, 21375, 23625, 25875, 28125, 30375, 32625, 34875, 7}; 8const char *dir_name[] = { 9 "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", 10 "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "N", "C" 11}; 12int dis_talbe[] = { 13 int( 0.25 * 60), int( 1.55 * 60), int( 3.35 * 60), int( 5.45 * 60), 14 int( 7.95 * 60), int(10.75 * 60), int(13.85 * 60), int(17.15 * 60), 15 int(20.75 * 60), int(24.45 * 60), int(28.45 * 60), int(32.65 * 60), 16}; 17 18int main() 19{ 20 int deg, dis; 21 cin >> deg >> dis; 22 deg *= 10; 23 int i = 0, j = 0; 24 while (i < 16 && deg >= deg_table[i]) i++; 25 while (j < 12 && dis >= dis_talbe[j]) j++; 26 if (j == 0) i = 17; 27 cout << dir_name[i] << ' ' << j << endl; 28 return 0; 29} 30

投稿2021/03/29 18:54

編集2021/03/29 19:32
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

smile_20200722

2021/03/30 01:41

kazuma-sさん、返信ありがとうございます。 このような書けるんですね。 書いていただいたソースコードで無事に通過できました。 一応、基本は変わりませんが、vectorクラスで書き直してみたのですが、こちらは部分的に通過できませんでした。 別質問にすべきかもしれませんが、この点についてお気づきの方がいらっしゃいましたら、お教えいただけると助かります。
kazuma-s

2021/03/30 03:30

通過できなかった場合の検証を自分ですることができないのでしょうか? その vector版のコードは、dir_name の要素が 17個しかないので、 dir_name.at(0)~dir_name.at(16) しか参照できません。 風力が 0 の場合、dir_name.at(17) を参照してしまいます。 また、"C" の前に "N" がないので、角度が 348.75°以上の場合、 N ではなく C になります。
smile_20200722

2021/03/30 05:43

kazuma-sさん、返信ありがとうございます。 無事に通過することができました。 自分でもコードを書いて毎回検証はしているのですが、もう少し時間をかけて考えたいと思います。
guest

0

c

1 if(wind_speed >= 0.0 && wind_speed <= 0.2) { 2 W = 0; 3 wind_direction = "C"; 4 } else if(wind_speed >= 0.3 && wind_speed <= 1.5) { 5 W = 1; 6...

wind_speed0.20.3の間になってしまったときに問題が発生します。他の箇所も同様です。
「小数点第2位で四捨五入しているからそんなことはありえない」と思うかもしれませんので
実験コードを用意しました。

dis = 12ですのでwind_speed = 0.2となりますが、wind_speed<=0.2の条件には引っかかりません。

c

1#include <stdio.h> 2int main(void){ 3 float dis = 12; 4 float wind_speed = dis/60; 5 wind_speed = round(wind_speed*10.0)/10.0; 6 7 printf("%f\n",wind_speed); 8 if(wind_speed<=0.2){ 9 printf("<="); 10 }else if(wind_speed>=0.3){ 11 printf(">="); 12 }else{ 13 printf("else"); 14 } 15} 16

実行結果はこちらになります。

0.200000 else

投稿2021/03/29 04:35

編集2021/03/29 04:48
ozwk

総合スコア13551

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

smile_20200722

2021/03/29 08:19

ozwkさん、返信ありがとうございます。 このような結果になるんですね。 こういう場合、どのようにコードを書き直せばいいのでしょうか?
kazuma-s

2021/03/30 00:51

> こういう場合、どのようにコードを書き直せばいいのでしょうか? 0.2 を浮動小数点数で正確な内部表現にすることはできません。 float の 0.2 と double の 0.2 とでは内部表現が異なります。 } else if(wind_speed >= 0.3 && wind_speed <= 1.5) { を } else if(wind_speed >= 0.3f && wind_speed <= 1.5f) { として、同じ float で比較を行う。 または、float deg, dis; を double deg, dis; にして、同じ double で比較を行う。
smile_20200722

2021/03/30 01:44

kazuma-sさん、こちらにも返信ありがとうございます。 私はfloatとdoubleについて理解できてないようなので、勉強し直します。
kazuma-s

2021/03/30 03:35

> または、float deg, dis; を double deg, dis; にして、同じ double で比較を行う。 deg, dis, wind_speed 全部を double にしてください。
smile_20200722

2021/03/30 05:48

kazuma-sさん、返信ありがとうございます。 やってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問