質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.35%
C++

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

Q&A

解決済

3回答

2858閲覧

AtCoderでなぜWAになっているか分からないため,ご教授お願いします。

Massy

総合スコア0

C++

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

0グッド

1クリップ

投稿2021/06/13 14:06

前提・実現したいこと

AtCoderでなぜWAになっているか分からないため,ご教授お願いします。
問題はこちらです

解説サイトを2つ拝見致しましたが,やり方が全く異なっていたので残念ながら解決には至りませんでした。

また,C++を勉強し始めたということもあり,もっと良い書き方やソースコードがあるだろうと存じておりますが
なぜこれではいけないのかを理解したいので,WAになってしまう理由を教え頂けないでしょうか。

最後まで読んでくださって,ありがとうございました。

発生している問題・エラーメッセージ

入力例をすべて試したところ,全て出力例と同じ結果が得られました。

該当のソースコード

C++

1#include <bits/stdc++.h> 2using namespace std; 3 4int main() { 5 6 int N; 7 int count = 1; 8 string S; 9 10 cin >> N; 11 12 for(int i = 0; i < N; i++) { 13 14 cin >> S; 15 16 if(S == "P") { 17 count *= 2; 18 } 19 20 else if(S == "W") { 21 count *= 2; 22 } 23 24 else if(S == "G") { 25 count *= 2; 26 } 27 28 else if(S == "Y") { 29 count = 0; 30 } 31 32 else { 33 cout << "error" << endl; 34 } 35 } 36 37 if(count % 3 != 0) { 38 cout << "Three" << "\n"; 39 } 40 41 else if(count % 3 == 0) { 42 cout << "Four" << "\n"; 43 } 44}

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

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

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

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

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

Crimson_Tide

2021/06/13 14:17

https://atcoder.jp/posts/20 一部古いコンテストはありませんが、atcoderではテストケースと出力結果が公開されています。 ABC089はあるので、テストケース使ってデバッグを試されてみてはいかがでしょうか。
1T2R3M4

2021/06/13 14:24

N=80 とかで試してみれば。 単純にYがあるか無いかでは駄目なのでしょうか。
Massy

2021/06/14 11:34

Crimson_Tideさん,1T2R3M4さん,アドバイスありがとうございます。 すでにAtCoderのコードテストとVScodeで環境構築したものを使用し,デバックをしていました。 しかし,N = 80など入力例以外や制約の最大値にちかいもので試していなかったのが問題で反省しています。 まだAtCoderもC++もプログラミングも始めたばかりですが, 今回の件でかなり勉強になりました,ありがとうございます。
guest

回答3

0

N=64で、順番はどうでもいいですから3色のデータを入れてみてください。
たぶん、fourと判別されるでしょう。お使いのC++コンパイラのint型が128bitだったりしたらボロは出ないでしょうが、題意としてはC++の規格上許されるintが16bitの系であってもプログラムは動かないといけないでしょう。

なぜ「2を乗ずる」と思ったのでしょうか? 別に1をかければよい話だし、そんなことしなくても、公式解説にあるように一個でもYを検出したら4色とすればよいだけの話です。

あと、プログラム的には

C++

1 if(count % 3 != 0) { 2 } 3 else if(count % 3 == 0) { 4 }

の部分、count%3 !=0でないなら必ずcount%3==0です。それをわざわざ判別させているのは「ムダ」です。

ところで、WAというのはソフトウェアエンジニアであれば当然誰でも知っていて説明なしに使える略語なのですか?

投稿2021/06/13 14:46

thkana

総合スコア7703

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

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

tomolatoon

2021/06/13 14:56

AtCoderの名前を出しているので、AtCoderのジャッジの判定結果として表示される、AC、WA、TLE、REなどは説明なしに用いてもいいのではないかと思います。
thkana

2021/06/13 15:11

他に相当する一般的な語がないわけでもなく、そのサイトのローカルルールで使われる略号でしかないのではないでしょうか? それをわざわざ「外」で使うのはどうなんでしょう。 まぁ、皆さんガンガン使うのでこっちも大体わかるようになっちゃいましたけど、どうにも気持ち悪さを感じます。
Massy

2021/06/14 11:29 編集

thkanaさん,回答ありがとうございます。 N=64で全てWで入力したところ,仰る通りFourと出力されました。 intの最大値は2147483647であるのに対し,今回の入力値の最大値(2の100乗, すなわち31桁)なので intの範囲を超えてしまい,プログラムは動くとしても正常ではないということですね。 1をかけるや,Yが入力されたらbreakするといったことは,今回の質問で記述したソースコードを 書き終わった後に思いついたのですが,何故これではいけないのかが知りたかったため質問致しました。 なるほど,上記の回答と同じく,条件が裏と表の場合,片方はelseを使用した方が良いのですね。 勉強になりました,ありがとうございます。 tomolatoonさんがおっしゃる通り,タイトルでAtCoderの名前を出しているので,回答をして頂ける人はAtCoderを使用したことがある方だと勝手に思い込んでいました。 ご指摘の通り,配慮に欠けていました,ありがとうございます。
guest

0

デバッグをしましょう

プロでもデバッグをしています。

ざっと見た感じ、条件が変。

wなら〜とかの時の処理は、

『y以外は2倍』なのに、結果の条件判断では『カウンタが3の倍数でないなら』となっている。

仮にyがないものであれば、

1×2=2
2×2=4
4×2=8
...

という風に、『2の倍数』になる。

質問のコードでは、2と3の倍数、つまり、最小公倍数である、6の倍数の時しか真にならない。

多分、サンプルの入力例ではたまたま、6の倍数になっていたんだと思いますよ。

それと、

if(count % 3 != 0) { cout << "Three" << "\n"; } else if(count % 3 == 0) { cout << "Four" << "\n"; }

ですが、ダメではないですが、ちょっともったいないですね。

日本語にしてみましょう。

『カウンタが3の倍数でないなら"Three"、
カウンタが3の倍数なら"Four"』

です。

なんか、仰々しくないですか?

だってお互い、裏と表ですよね。

だから、

if(count % 3 != 0) { cout << "Three" << "\n"; }else{ cout << "Four" << "\n"; }

とシンプルにやればいいのでは?


[追記0]

それと、問題文を読むと、

桃色、白色、緑色 → Three 桃色、白色、緑色、黄色 → Four

ですよね。

よーく見てください。

桃色から緑色までは共通で、
『黄色があるかどうか』で分岐しています。

並びが完全固定だと面倒ですが、
順不同らしいので、

『黄色が一つでもあれば"Four",
そうでないならThree"』

とした方が楽かも。

そうすれば、

for文でリニアサーチして、黄色があればフラグで…

みたいにすれば簡単にいける。

ただ、勉強としては『正しいこと』よりも、

**『自分で考え、自分で調べる』が重要ですので、
**
悪くはないと思いますよ。

投稿2021/06/13 14:56

編集2021/06/13 15:17
BeatStar

総合スコア4962

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

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

Massy

2021/06/14 11:11

BeatStarさん,回答ありがとうございます。 条件がおかしいと記述されていますが,そうでしょうか。 y以外のときは常に2の倍数であるため,3のあまりは常に1か2となり "Three"が表示されると考えられます。 また,yのときはcountという変数が0になるため,仮にy以外が入力されても0となり あまりも0のため"Four"になると考えました。 else ifではなくelseを使用したらどうかの件ですが, 条件が裏と表のときは片方をelseにした方が良いということですね。 ご指摘ありがとうございます,勉強になりました。 追記のYだけで分岐の件ですが, それだと桃色,白色,緑色,黄色の4つ以外が入力されたときにerrorが出せないと 思ったので,それぞれ書いていました。 しかし,AtCoderの制約外だと,errorを出すようにしないといけないと勝手に思い込んでいたのですが そうではなく,そもそも制約外(今回でいうP, W, G, Y以外のもの)は絶対に入力されないという前提条件だったのですね。 これも勉強になりました,ありがとうございます。 長文かつ追記までして下さり,重ねてお礼申し上げます。
BeatStar

2021/06/14 11:29

条件式については、書いてるうちにごちゃごちゃしてきたのでまぁアレですが。 ですがp or w or ...については、オリジナルの問題の『制約』の項目に書かれています。 私も以前この制約の部分を見逃していて結果が合わないことがありました。 なので制約等の部分も見たほうがいいと思いますよ。
Massy

2021/06/14 11:38

いえ,問題を解く際に制約等の部分は見ていたのですが 制約を満たすソースコードを書くのか,制約内の入力に対処したソースコードを書くのか 分からず勘違いしていたので余計なコードを書いていました。
BeatStar

2021/06/14 11:50

あ、そっちですか。 こういうのは、大抵、『以下の前提で入力される』と言う意味だと思いますよ。
Massy

2021/06/14 11:53

はい,その通りでしたね。 次の問題からは気を付けます。
guest

0

自己解決

2乗をやめたやり方で解決する。(結論:intで変数を作ったのがいけないor2乗でやるのがよくない?だった)

投稿2021/06/15 05:54

Massy

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問