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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

597閲覧

x以下の最大のべき数を求めたい

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2018/06/05 08:26

イメージ説明

前提・実現したいこと

https://beta.atcoder.jp/contests/abc097/tasks/abc097_b
この問題を解きたいです。
自分で考えた添付の画像通りに沿ってコードを書きました。
最初の条件分岐ですがb!=1をb==1に直していますが
そのほかは大きな変更はありません。

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

コンパイルエラーは出ていませんが x=1,2のとき以外はどこかでループしていてプログラムが終わらず x=2のときでもまともな答えが出ません。

該当のソースコード

c

1#include<stdio.h> 2//b^pを計算する関数 3int myCalc(int b, int p) 4{ 5 int i = 1; 6 7 while(i <= p-1){ 8 b=b*b; 9 } 10 11 return b; 12} 13 14int main(void) 15{ 16 int x=0, b=1, p; 17 int max=1; 18 19 scanf("%d", &x); 20 21 for(;;){ 22 p=1; 23 if(b==1){ 24 if(x==myCalc(b, p)){ 25 printf("1\n"); 26 return 0; 27 }else{ 28 b++; 29 printf("b:%d\n", b); 30 } 31 } 32 printf("stop\n"); 33 while(x > myCalc(b, p)){ 34 p++; 35 printf("p:%d", p); 36 } 37 if(p!=1){ 38 if(myCalc(b, p) > max) max = myCalc(b, p); 39 b++; 40 printf("b:%d\n", b); 41 }else{ 42 printf("%d\n", max); 43 return 0; 44 } 45 printf("***\n"); 46 } 47} 48

試したこと

プリントデバッグで、stopまでしか表示されないことがわかりました。
理由がわかりません。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答3

0

stopまでしか出ないということは、次のwhileループ内のprintfは出力されないということですね。
ということはwhileループの条件で呼んでいるmyClac関数が戻ってこないということです。
myCalc関数を見るとまたwhileループしていますが、ループ条件に使用しているipがループ内で変動していません。
よってここで無限ループになっているのではないでしょうか。
ここ↓

c

1 while(i <= p-1){ 2 b=b*b; 3 }

投稿2018/06/05 08:40

ttyp03

総合スコア16998

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

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

退会済みユーザー

退会済みユーザー

2018/06/05 08:49

回答ありがとうございます。 いわれてみればたしかにmyCalcで止まってる以外 考えられませんでしたね。。。 ありがとうございました。 さっさと完成させます。
guest

0

まず、myCalcの時点で間違っています。b = b * b;とすると、繰り返すたびに2乗、2乗で増えていくので、「bのp乗」にはなりません。

投稿2018/06/05 08:32

maisumakun

総合スコア145183

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

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

退会済みユーザー

退会済みユーザー

2018/06/05 08:51

回答ありがとうございます。 bを固定するために別のにコピーする必要がありましたね。。 たとえば i=b; for(j=1; j<=p-1; j++){ b=b*j; } だとできました。 ありがとうございました。
mather

2018/06/05 16:13

そこは j ではなく i を掛けるべきなのでは…。
退会済みユーザー

退会済みユーザー

2018/06/05 21:50

回答ありがとうございます。す。 ご指摘ありがとうございます(iで固定した意味)
guest

0

ベストアンサー

こんにちは、原因の方はほかの方の回答にあるのでここでは別解を言いたいと思います。
参考になったら幸いです。
ソースを見た感じ少しfor文の中が複雑になっているのでもっと簡潔にできないかなぁと思いました。

まず例の10の時ですが、10に最も近いべき乗数を求めるとき底の最大値は√10の整数部分の3となり、そこから指数部分を2から1ずつ増やし10を超えないべき乗数まで算出します。

なぜ底の最大値は平方根の整数部分なのか

べき乗数の指数部分の最小値は2です。つまり、底が平方根の指数部分を超えると入力した値より大きいべき乗数が出ます。例の10の時、例えば4のべき乗を考えると4^2 > 10となり計算する必要はありません。
つまり、底が3以下の場合のべき乗数で10以下のものだけを考えればいいことになります。

話を戻します。

実際に、計算すると
2^2 = 4 , 2^3 = 8 (2^4 = 16は10を超えるので底が2のループは終了)
3^2 = 9, (3^3 = 27は10を超えるので底が3のループは終了)

となり、最大値は9となります。べき乗数を求め、より大きいものが出るとき最大値が更新するようにします。これを2重for文でやればいいです。

c

1int answer = 1; 2 3for(i = 2; pow(i,2) <= n; i++){ 4 for(j = 2; pow(i,j) <= n; j++){ 5 if(answer <= pow(i,j)){ 6 answer = pow(i,j); 7 } 8 } 9} 10 11printf("%d\n",answer);

for文の条件文のところに <=と イコールを付けることで入力した数値がべき乗数の時も対応しています。
また、入力した数値が1の時ですが、このときはまずfor文を通らないので初期値answer = 1が答えとなります。

ちなみに

私も最初はaのb乗を求める関数を自分で作ってました。しかし、C言語には<math.h>をインクルードすると
pow関数を使うことができます。pow(a,b)はaのb乗を表しています。
詳しくはpow関数をご覧ください。

投稿2018/06/05 13:09

編集2018/06/06 00:23
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2018/06/05 13:11

書いたソースコードを全部載せようかとおもいましたが 全部載せると当サイトの規約に反するかもしれないので重要なところだけをピックアップしました。(もし全部載せていいのなら全部載せますが....)
退会済みユーザー

退会済みユーザー

2018/06/05 23:15

回答ありがとうございます。 xの整数部をAとしたとき、A<=ルートx<A+1となって 何乗してもルートx<A+1という関係が変わらない、というのを利用して pow(i, 2) <= nとされているところになるほどと思いました。 教えていただいたやり方を参考にして完成できました。 丁寧な回答ありがとうございました。
退会済みユーザー

退会済みユーザー

2018/06/06 00:24

べき乗数は底、指数部分ともに2以上なのでjの初期値は2でした。すみません。その部分を訂正しました。
退会済みユーザー

退会済みユーザー

2018/06/06 00:26 編集

そうですね。for(i = 2; pow(i,2) <= n; i++)で、底のiが2から入力した整数の整数部分以下を動き、 for(j = 2; pow(i,j) <= n; j++)で、指数部分jが2から「iのj乗がnを超えない」数値まで動き 最大値を求めていく感じです。 お役に立ってうれしいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問