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

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

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

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

Q&A

解決済

1回答

1147閲覧

codelic(プログラミングサイト)のdemo taskの問題で、不正解コードのダメな箇所がわかりません。

ratera

総合スコア54

C++

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

0グッド

0クリップ

投稿2021/12/01 10:08

codelic(プログラミングサイト)のdemo taskの問題で、不正解コードのダメな箇所がわかりません。
答えに違いが出る理由を教えてほしいです。

問題文

  • codelic(プログラミングサイト)のdemo task
  • テストプログラムの入力値は非公開のためわかりません
  • 問題文はこちらなどにものっています。

試したこと

  • C1カバレッジでの動作確認は共に同じとなることを確認した
  • codelic側テストプログラムでは、performance testは全件OK(4/4)した。一方、correctness test casesは1/5となり正しく期待値を出せていないケースがある
  • 別の方法で正解コードは出せた。ただし、正解コードと不正解コードを比較してどこに問題があるのかわからない

code

c++

1//不正答コード 2int solution(vector<int> &A) { 3 int ans=1; 4 int Asize=A.size(); 5 sort(A.begin(),A.end()); 6 7 //A[i]の最大値が0以下である場合は、1を返す。A={-1,-3}のケース; 8 if(A[Asize-1]<=0) return 1; 9 10 //A[]の最大値が1以上。A={-1,1,3,6,4,1,2};のケース 11 for(int i=0; i<Asize;i++){ 12 if(ans>=A[i]){//条件① 13 }else if((ans+1) ==A[i]){//条件② 14 ans++; 15 }else{//条件③ 16 return ++ans; 17 } 18 } 19 20 //A={1,2,3}のケース、正の値がきちんと 21 return ++ans; 22}

不正答コードの、A={-1,1,3,6,4,1,2};のケースの動作の参考として、以下のスクリーンショットを添付します。
不正答コードの、A={-1,1,3,6,4,1,2};のケースの動作説明

以下は、正解したコードになります。

c++

1//正答したコード 2int solution(vector<int> &A) { 3 int ans=1; 4 int Asize=A.size(); 5 sort(A.begin(),A.end()); 6 7 // rep(i,Asize){ 8 for(int i=0; i<Asize;i++){ 9 if(A[i] <= 0){ 10 11 }else if(A[i] == ans){ 12 ans++; 13 } 14 } 15 return ans; 16}

code全文

c++

1//不正解コード 2#define _GLIBCXX_DEBUG//配列外参照のデバッグ用 3 4#include <bits/stdc++.h> 5#define rep(i, n) for (int i = 0; i < (n); ++i) 6#define rep1(i, n) for (int i = 1; i <= (n); ++i) 7using namespace std; 8using ll = long long; 9using P = pair<int, int>; 10 11//1 <= int N <= 10^5 12//int A[i]:-10^6 to 10^6 13int solution(vector<int> &A) { 14 int ans=1; 15 int Asize=A.size(); 16 sort(A.begin(),A.end()); 17 18 //A[i]の最大値が0以下である場合は、1を返す。A={-1,-3}のケース; 19 if(A[Asize-1]<=0) return 1; 20 21 //A[]の最大値が1以上。A={-1,1,3,6,4,1,2};のケース 22 for(int i=0; i<Asize;i++){ 23 if(ans>=A[i]){ 24 }else if((ans+1) ==A[i]){ 25 ans++; 26 }else{ 27 return ++ans; 28 } 29 } 30 31 //A={1,2,2,3}のケース 32 return ++ans; 33} 34 35int main(){ 36 {vector<int> A={-1,1,3,6,4,1,2}; 37 cout << solution(A) << endl;} 38 {vector<int> A={1,2,2,3}; 39 cout << solution(A) << endl;} 40 {vector<int> A={-1,-3}; 41 cout << solution(A) << endl;} 42 return 0; 43}

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

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

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

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

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

episteme

2021/12/01 11:19

どんな問題を解いたコードなのかわからん。
ratera

2021/12/01 15:21

問題文の書き方がわかりづらくすみません。 問題文の箇所に2か所リンクを貼っていましたが、次回は他の方の書き方を調べたうえで、伝わりやすくしています。 (一応、問題に著作権があるようでしたのでベタ貼りすることは控えておりました。ご容赦ください)
guest

回答1

0

ベストアンサー

こちらのケースをデバッガで追えばわかるでしょう。

c++

1 {vector<int> A = { 2 }; 2 cout << solution(A) << endl; }

投稿2021/12/01 12:05

actorbug

総合スコア2429

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

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

ratera

2021/12/01 15:18

ありがとうございます。理解できました。 自分の回答の穴を見つけられるようにもなりたいし、もっとバグの入り込む余地のないシンプルなアルゴリズムを考えられるようになりたい一問でした<m(_ _)m> ご回答いただき、ありがとうございます。
ratera

2021/12/01 15:27

【解決メモ】 以下のケースにおいて、ansの初期値が1のため、出力が3になるバグがあった。 ansの初期値を1にすると、A[i]が1を含んでいなかった場合に出力が1とならない。 >  {vector<int> A = { 2 }; cout << solution(A) << endl; } solution内の、ansの初期値を0にすることで、全ての正答ケースをパスすることを解決しました。 ```c++ int solution(vector<int> &A) { int ans=0; int Asize=A.size(); sort(A.begin(),A.end()); //A[i]の最大値が0以下である場合は、1を返す。A={-1,-3}のケース; if(A[Asize-1]<=0) return 1; //A[]の最大値が1以上。A={-1,1,3,6,4,1,2};のケース for(int i=0; i<Asize;i++){ if(ans>=A[i]){ }else if((ans+1) ==A[i]){ ans++; }else{ return ++ans; } } //A={1,2,2,3}のケース return ++ans; } ```
actorbug

2021/12/01 20:59

一応、私がこちらのケースを思いついた時の流れを説明します。 ・ソートされている前提なら、for文内の条件分岐に抜けはなさそう ・そうなると境界付近があやしい ・動作が変わる境界は 1 だから、1 をまたぐパターンをいくつか試してみよう 最初に思い付いたパターンは{0, 2}でした。
ratera

2021/12/02 02:03 編集

ありがとうございます。デキる方がどのような視点で原因を絞っていくのかは、とても参考になる情報です。 入力値であるA[i]の境界で考えると、0,1,2の境界を疑うのは仰るとおりでした。 1を飛ばした0,2のケースに気づけるかはまだ自信がもてていませんが、こちらもどうしたら気づけるか考えていこうと思います。 ご丁寧にアドバイスいただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問