crignactor
@crignactor (クリグナ)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

競プロで、変数の宣言の真下で入力を代入しないとエラーになるのですが、その理由などを教えていただきたいです。

Q&A

Closed

解決したいこと

競プロの入力について質問があります。まず一番伺いたいことから申し上げると、ある変数に入力を代入したい場合、変数を宣言した真下に「cin >> (変数名)」としなけレバならならず、間に他の入力に使う変数などの宣言を挟んではいけないのかということについて伺いたいです。次点として、下のエラーについてどんなもので原因はなんなのかを教えていただきたいです。
(私はプログラミング歴1ヶ月競プロ歴2週間弱の理系大学生で経験が浅いので、全く的外れなことを聞いてしまっているかもしれないのですが、そこはご容赦ください。)

このように疑問を持った経緯としては
https://atcoder.jp/contests/dp/tasks/dp_c
の問題を解いて提出した際、エラーが起き、その原因を検証していたというものがあります。結果としては、以下のような入力のコードの違いによりエラーが起こっているのだとわかりました。その違いとは「int main(){int N;」の次のコードが入力か二次元配列の宣言かという違いです。

実行時エラーの起きたコード

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

int main(){
 int N;
 vector< vector <long long>> hapi(N,vector<long long>(3));
   cin>>N;
    for (int x=0;x<N;x++){
       for (int y=0;y<3;y++){
          cin>>hapi[x][y];
       }
    }


//definition of DP
   vector <vector<long long>> dp(N+1,vector<long long>(3,0));

   for(int i=0;i<N;i++){
            dp[i+1][0]=max(dp[i][1],dp[i][2])+hapi[i][0];
            dp[i+1][1]=max(dp[i][0],dp[i][2])+hapi[i][1];
            dp[i+1][2]=max(dp[i][1],dp[i][0])+hapi[i][2];
    
    }
    int A=max(dp[N][0],max(dp[N][1],dp[N][2]));
   cout<<A<<endl;
}


エラー画像

スクリーンショット 2022-10-01 15.31.10.png
参考までに正解の時の画像も載せて置きます。
スクリーンショット 2022-10-01 15.38.28.png

正解を得られたソースコード

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

int main(){
 int N;
  cin>>N;
 vector< vector <long long>> hapi(N,vector<long long>(3));
    for (int x=0;x<N;x++){
       for (int y=0;y<3;y++){
          cin>>hapi[x][y];
       }
    }


//definition of DP
   vector <vector<long long>> dp(N+1,vector<long long>(3,0));

   for(int i=0;i<N;i++){
            dp[i+1][0]=max(dp[i][1],dp[i][2])+hapi[i][0];
            dp[i+1][1]=max(dp[i][0],dp[i][2])+hapi[i][1];
            dp[i+1][2]=max(dp[i][1],dp[i][0])+hapi[i][2];
    
    }
    int A=max(dp[N][0],max(dp[N][1],dp[N][2]));
   cout<<A<<endl;
}
0

1Answer

変数Nの中身が未定義1のまま,配列長の単位として使っているからエラーになっています.Nに依存しない処理が間にあるなら問題なく実行できるでしょう.

  1. たまたまコンピュータが確保してきた変数のアドレスに入っている何かの値が取り出されます.

1Like

Comments

  1. @crignactor

    Questioner

    そういうことだったんですね。今試してみて実感もできました。
    入力につかう変数の下にはその変数に依存する処理は書かないようにしようと思います。
    ありがとうございました(毎度のことではありますが)。
  2. 逐次実行の原則を意識して書く,と言うことになるんでしょうか,私は上のようにならないよう,標準入力からの受け取りは変数宣言直後にしています.

    色んな人の回答を見るとわかりますが,変数宣言と値の受け取りを関数にまとめてる人もいます,探してみると良いでしょう.
  3. @crignactor

    Questioner

    私もそうしようと思ってます。関数があるコーディングも速い気がするので探してみます。
    本当に、色々ありがとうございます!

Your answer might help someone💌