• 締切済み

icpcの過去問

問題→ http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1147&lang=jp 自分の回答→ #include <iostream> using namespace std; int numbers[105]; int order(int n,int num){ if(num==0){numbers[0]=n;} else{ for(int i=0;i<num;i++){ if((numbers[num-(i+1)])>n){//cout << "here1"; numbers[num-i]=numbers[num-(i+1)];//cout << "here2"; numbers[num-(i+1)]=n;//cout << "here3"; } } } return 0; }//昇順に並べる int main(){ int n; while(cin>>n,n){ int count,answer; for(int i=0;i<n;i++){int Numb; cin >> Numb;if(i==2){cout << "here";} order(Numb,i); count++; }//昇順に要素が並んだ for(int i=1;i<count-1;i++){ answer += numbers[i]; } answer = answer/(count-2); cout << answer << endl; } } 実行結果→ 3 7 6 5 Bus error となってしまいます。最後の入力の時に、cinされずにbuserrorになるのですがなぜなのでしょうか。

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

while(cin>>n,n) って, 実際にはかなり危険なんですよ. この問題のように「最後に必ず 0 が入力される, そうでないようなものは知らん」って態度ならいいんだけど, 人間の入力を想定する場合は「想定しない入力」も考えておかないとダメ. ということで, 普通はループの条件は cin >> n だけにしておき, ループ内部で「n が 0 かどうか」の判定をすることが多かったりする. あと, for の条件が i<n で不十分な理由, あります? まぁ, そもそも 0 クリア自体が不要だけど. む, order (って名前も変だが) の中もちょっと簡単にできそうだ.

bcbcbc
質問者

お礼

色々ありがとうございました!

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

あとついでだけど, while(cin>>n,n) は何を意図した書き方なんでしょうか. こんな書き方を推奨する人間がいるとは想像もできないのですが.

bcbcbc
質問者

補足

>for文の条件 ここまで0にしとけば大丈夫だろって考えです。0にし忘れがないように多めにと思って・・・、とか言ったらまたお叱りを受けますね、すみません。 >while(cin>>n,n) cin>>nを実行して、なおかつn!=0のときはループする、という意図です。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

bus error になる理由は #2 の通り. あと, 書き換えたあとのプログラムで最後の for ループはなんで for(int i=0;i<=n;i++) なの?

全文を見る
すると、全ての回答が全文表示されます。
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

> cinされずにbuserror プログラムを見ると、「cinが終わって」いるはずです。 最初の値3 がnになって、入力する個数 そのあと3つ値が入力されている。 > int count,answer; とあるだけで、countもanswerも初期化されていません。 よって、何が入っているかわかりません。 例えば、countが200だったりします。すると > for(int i=1;i<count-1;i++){ > answer += numbers[i]; > } のループで、iは105以上の値を取ります。 numbers[105]と宣言されていますので、その範囲外をアクセスすることになります。 ○ 変数は宣言しただけでは値は不定。他言語のように0やnullで初期化されたりしない(特定の場合を除く)。 ○ 配列の範囲外をアクセスした場合、その動作は未定義。  他言語のような「配列の範囲外エラー」になると決まっているわけではない。  なにかのエラーになるかもしれないし、何事も無かったように動作するかもしれないし、ハードディスクが破壊されるかもしれない。  何が起こっても「C/C++言語の仕様として『正しい』」 C/C++を使う上で覚えておかなければならない基本事項です。 ICPCの過去問という「応用問題」をやっているようですが、「応用問題」は「基礎」をマスターした上でのものです。 これまでの質問を見るかぎり、まだまだ基礎能力が不十分に見えます。 これくらいは自分で修正できるくらいに、基礎能力を高めるようにしてください。

bcbcbc
質問者

お礼

ありがとうございました!!

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

なるべく変数は初期化してください.

bcbcbc
質問者

補足

ありがとうございました。 変数から見直して下記のようになり、無事自動添削でacceptedがもらえました。 #include <iostream> using namespace std; int numbers[105]; int order(int n,int num){ if(num==0){numbers[0]=n;} else{ for(int i=0;i<num;i++){ if((numbers[num-(i+1)])>n){ numbers[num-i]=numbers[num-(i+1)]; numbers[num-(i+1)]=n; } else {numbers[num-i]=n;break;} } } return 0; }//昇順に並べる int main(){ int n; while(cin>>n,n){ for(int i=0;i<n;i++){int Numb; cin >> Numb; order(Numb,i); }//昇順に要素が並んだ /*for(int i=0;i<n;i++){ cout << numbers[i]; }*/ int answer=0; for(int i=1;i<(n-1);i++){ answer += numbers[i]; } answer = answer/(n-2); cout << answer << endl; for(int i=0;i<=n;i++){ numbers[i]=0; } } } 変数の初期化含め色々と間違っていたのはわかるのですが、どうしてbuserrorが出ていたのかがわかりません。もしよろしければ教えてください。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • POJ 2718

    #include <iostream> #include <cstdio> #include <algorithm> #include <vector> using namespace std; int numbers[10]; int length; int n; int permutation(int num[10]){ int i; int oneco=0; for(i=0;i<length;i++){ if(num[i]){oneco++;} } int length2 = length-oneco; if((oneco==length)||(oneco==0)){return 1000000000;} if(abs(length2-oneco)>=2){return 1000000000;} vector<int> one; vector<int> two; for(int i=0;i<length;i++){ if(num[i]){one.push_back(numbers[i]);} else{two.push_back(numbers[i]);} } int len1 = one.size(); int len2 = two.size(); //cout << len1 << len2 << endl; // int num1[10];int num2[10]; vector<int> num1; vector<int> num2; //cout << one[1] << one[2] << endl; int count1=0;int count2 = 0; sort(one.begin(),one.end()); sort(two.begin(),two.end()); do{ int num=0; for(int i=1;i<len1;i++){ int onei = one[i]; for(int i2=0;i2<i;i2++){ onei = onei*10; } num = num + onei; }//cout << num << endl; if(one[0]==0){num = num;} else {num = num + one[0];} num1.push_back(num); //cout << num << endl; count1++; }while(next_permutation(one.begin(),one.end())); do{ int num = 0; for(int i=1;i<len2;i++){ int twoi = two[i]; for(int i2 =0;i2<i;i2++){ twoi = twoi*10; } num = num + twoi; // cout << num << endl; }//cout << "here" << num << endl; if(two[0]==0){num = num;} else {//cout << num ; num = num + two[0]; //cout << " " << num << endl; } num2.push_back(num); //cout << "here" << num << endl; count2++; }while(next_permutation(two.begin(),two.end())); int ans = 1000000000; //cout << len2; int dummy1 = 1; for(int x=1;x<len1;x++){ dummy1 = dummy1*10; }//cout << dummy1; int dummy2 = 1; for(int x=1;x<len2;x++){//cout << dummy2<< endl; dummy2 = (dummy2)*10; //cout << dummy2<< endl; }//cout << dummy2; for(int i=0;i<count1;i++){//cout << num1[i] << dummy1 << endl; if((num1[i]%dummy1)==num1[i]){if(num1[i]!=0){continue;}} for(int i2=0;i2<count2;i2++){ if((num2[i2]%dummy2)==num2[i2]){if(num1[i]!=0){continue;}} ans = min(ans,abs(num1[i]-num2[i2])); } } return ans; } //int permutation(int i[10]){return 1;} int dfs(int i,int num[10]){ if(i==length) return permutation(num); num[i]=0; int ans1 = dfs(i+1,num); num[i]=1; int ans2 = dfs(i+1,num); return min(ans1,ans2); } int main(){ cin >> n; getchar(); for(int i=0;i<n;i++){ /*for(length=0;length<10;length++){ cin >> numbers[length]; char c = getchar(); if(c=='\n'){break;} }*/ string str; while(1){ char c = getchar(); if(c=='\n'){break;} str += c;} length = 0; for(int i2=0;i2<str.length();i2=i2+2){ numbers[length] = (int)str[i2]-'0'; length++; } // cout << length; int dummy[10] = {0,0,0,0,0,0,0,0,0,0}; cout << dfs(1,dummy) << endl; } } 上記のどこが間違っているか教えてください。POJの2718です。書いてあるテストは通りました。

  • 設定した値が意図せぬ値に

    POJ 3176の問題です。 http://poj.org/problem?id=3176 #include <iostream> #include <algorithm> #define MAX 100 using namespace std; int main() { int n; cin >> n; int line[n-1][MAX]; int num[n-1][MAX]; cin >> line[0][0]; if(n==0) { cout << 0 <<endl; return 0; } else if(n==1) { cout << line[0][0] << endl; return 0; } for (int i =1;i < n;i++) { for (int j=0;j < i+1;j++) { int x; cin >> x; line[i][j]= x; } } for (int k= 0 ; k<n;k++) { num[n-1][k]= line [n-1][k]; } for (int k= n-2; k > 0 ; k--) { for (int l=0 ; l<k+1; l++) { num[k][l] = max (num[k+1][l],num[k+1][l+1]) + line[k][l]; } } num[0][0] = max(num[1][0],num[1][1]) + line[0][0]; cout << line[0][0] <<" "<<num[0][0]<<endl; return 0; } 入力 4 3 1 3 1 2 3 1 3 4 5 出力 1 12 最後に出力でline[0][0]をするようにしているのはバグチェックのためです。 ここで僕がわからないのはどうしてline[0][0]が3で宣言し、ほかでいじっていないにも関わらず、最後に1になっているのかということです。 どなたかわかる方がいらっしゃったらよろしくお願いします。

  • 点数の大きい順に出力する

    #include <iostream> using namespace std; int main() { const int num = 5; int test[num]; cout << num << "人の点数を入力して下さい。\n"; for(int i=0; i<num; i++){ cin >> test[i]; } } } } for(int j=0; j<num; j++){ cout << j+1 << "番目の人の点数は" << test[j]<< "です。\n"; } return 0; } ---------- の for(int s=0; s<num-1; s++){ for(int t=s+1; t<num; t++){ if(test[t] > test[s]){ int tmp = test[t]; test[t] = test[s]; test[s] = tmp; の部分が理解できません。 s<num-1 は 0<4; ということでしょうか? 値が5つ入力されその値が if(test[t] > test[s]){ にどの様に挿入されるのかが 解りません。  

  • ややこしいコード

    #include<iostream> using namespace std; int main() { const int num = 5; int test[num]; cout << num << "人の点数を入力して下さい。\n"; for (int i = 0; i < num; i++) { cin >> test[i]; } for (int s= 0; s < num - 1; s++) { for (int t = s + 1; t < num; t++) { if (test[t] > test[s]) { int tmp = test[t]; test[t] = test[s]; test[s] = tmp; } } } for (int j = 0; j < num; j++) { cout << j + 1 << "番目の人の点数は" << test[j] << "です。\n"; } return 0; } 配列を並べ替える(ソート)する練習コードなんですが、 ちょっとややこしいので解りやすく教えて欲しいです。 因みに点数は、 22,80,57,60,50の順でお願いします。

  • c++について

    入力した値が123または456で一致したら一致と表示したいのですがどうfor文を回すか分かりません。 ご助力願います_(._.)_ class N { bool hit(const char* a[],const char* b) {   for(int i=0;i<*a[i];i++) if(*a[i]!=b[i]) { return false; } return true ; } public: N() { const char* a[ ]={ "123","456"}; char b[4]; int num; cin>>num; sprintf_s(b, 4, "%03d", num); if(hit(a,b)) cout<<"一致"; else cout<<"不一致"; } };

  • VC++でプログラムの勉強をしています。

    プログラムは最近はじめたばかりです。While文とif文を使ってクイズを作ってみたところ、一個目のsinで入力を求めているところから無限ループになってしまいました。色々調べてcin.cler()とsin.ignore()を入れたりもしてみましたが上手くいきませんでした。どこを間違えているのでしょうか? //クイズ #include <iostream> using namespace std; int main()//cin.clear();cin.ignore();???? { int a; int b; while(1) { cout<<"ネコ型のロボットが出てくるアニメといえば?"<<endl; cout<<"A)ドラえもん B)ドラエもん C)ほりえもん D)サザエさん"<<endl; cin>>a; if(a=='A') { cout<<"ファイナルアンサー?"<<endl; cout<<"Y)Yes N)NO"<<endl; cin>>b; if(b=='Y'){break;} if(b=='N'){cout<<"ゆっくり考えてね!!"<<endl;} if(b!='Y'||'N'){cout<<"正しく入力してね!"<<endl;} } if(a=='B'||'C'||'D') { cout<<"ファイナルアンサー?"<<endl; cout<<"Y)Yes N)NO"<<endl; cin>>b; if(b=='Y'){cout<<"残念!!"<<endl;} if(b=='N'){cout<<"ゆっくり考えてね!!"<<endl;} } if(a!='A'||'B'||'C'||'D'){cout<<"正しく入力してね!"<<endl;} } cout<<"正解!!"<<endl; }

  • 配列の練習問題

    #include<iostream> using namespace std; //count関数の宣言 int count(char str[], char ch); int main() { char str[100]; char ch; cout << "文字列を入力して下さい。\n"; cin >> str; cout << "文字列から探す文字を入力して下さい。\n"; cin >> ch; int c = count(str, ch); cout << str << "の中に" << ch << "は" << c << "個あります。\n"; return 0; } //count関数の定義 int count(char str[], char ch) { int i = 0; int c = 0; while (str[i]) { if (str[i] == ch) c++; i++; } return c; } こんにちは。 この問題の解答のプログラムの意味がイマイチ解らないので良かったら教えて下さい。 確認がてらに質問します。 よろしくお願いします。

  • C++で分からないプログラムがあるんですが

    #include <iostream> #include <cmath> using namespace std; int main() { static const int N = 2; double va[N]={3,-4}; double vb[N]={4,3}; double a,b; double p; for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) { } } cout << "va + vb = (" ; for (int i = 0; i < N; ++i) { cout << va[i] + vb[i]; if (i < N - 1) { cout << ", "; } } cout << ")" << '\n'; cout << "va - vb = (" ; for (int i = 0; i < N; ++i) { cout << va[i] - vb[i]; if (i < N - 1) { cout << ", "; } } cout << ")" << '\n'; p = 0; for (int i = 0; i < N; ++i) { p += va[i] * vb[i]; } cout << "va・vb = " << p << '\n'; a = 0; for (int i = 0; i < N; ++i) { a += va[i] * va[i]; } a = sqrt(a); b = 0; for (int i = 0; i < N; ++i) { b += vb[i] * vb[i]; } b = sqrt(b); if (a * b != 0) { cout << "cosθ = " << p / (a * b) << '\n'; } return 0; } これで、ベクトルの加減とベクトルの内積とcosθが出るんですが、2つのベクトルを適当に初期化しないといけないんですが、初期化ってこれで初期化ってできてますか?

  • c++ で *の逆三角旗を作りたいです

    普通の三角旗はできましたが逆三角旗が分かりません 例えば3と入力したら * ** *** ** * こんな感じで出力させたいのですが考え方が分かりません 普通の方のコードはこんな感じです int i, j; cin>>num; for (i = 1;i <= num;++i) { for (j=1;j<=i;j++) { cout << "*"; } cout << endl; } for (i = 1;i <= num-1 ;i++) { for (j=1;j<=num-i;j++) { cout << "*"; } cout << endl; } cout << endl;

  • なぜエラーになるのかわかりません

    入力した文字列からthがいくつ含まれるのかというプログラミングを作りたいのですが>if( sentence[i] == 'th' )の部分で 「比較において定数が範囲外」というエラーがでてしまいます。eなどひとつの文字でならでないのですが・・・よくわからないので教えてください #include <iostream.h> main() { const int Max_Length = 80 ; char sentence[Max_Length] ; int count ; int th ; for(;;){ // 文字列の入力 cout << "\n 文字列を入力して下さい(英数字のみ) >> " ; cin.getline( sentence, Max_Length ) ; // 文字数を数える count = 0 ; while( sentence[count] != '\0' ){ count++ ; } //thの数を数える th = 0 ; for( int i = 0 ; i <= count ; i++ ){ if( sentence[i] == 'th' ) th++ ; } // 文字列の再表示と結果の表示 cout << "\n 文字列= " << sentence << endl ; if( th == 0 ) cout << "thは含まれません" << endl ; cout << "thの数は" << th << endl ; } }

このQ&Aのポイント
  • LIFEBOOK UH75/E3のバッテリーを交換する方法を教えてください。
  • 富士通FMVのLIFEBOOK UH75/E3のバッテリー交換手順を詳しく教えてください。
  • LIFEBOOK UH75/E3のバッテリーの取り外しと交換方法を教えてください。
回答を見る

専門家に質問してみよう