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

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

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

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

Q&A

解決済

3回答

763閲覧

n桁以下の最大の3のべき乗

nagano-yuhi

総合スコア39

C

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

0グッド

0クリップ

投稿2020/07/29 16:23

正整数 n ( 0 < n < 80 ) に対して, n桁以内の最大の3のベキ乗数を左詰めで書き出すプログラムを作れ。

【入力】
正整数 n ( 0 < n < 80 ) 1つ。

【出力】
1行として書き出す(末尾に改行を書き出すこと)。

【例】
入力1
1
出力1
9

が問題と出力結果です。自分のコードで納得いっているのですが出力が上手くいきません。どこが間違っているのか指摘していただきたいです。

#include <stdio.h> int main(void){ int n; scanf("%d", &n); int x=1; int i; int digit=0; for(i=0;i<1000;i++){ x=x*3; while(x!=0){ //xの桁数を計算 x=x/10; ++digit; } if(digit>n+1){ break; } } printf("%d\n", x/3); //最後nよりも1桁多い最小のxだから割る3 return 0; }

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

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

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

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

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

guest

回答3

0

あちこちおかしいです。変数の役割を自分で把握仕切れていないのが原因。

xはどんどん3を掛けていく変数のつもりだったはずなのに、0になるまで10で割っている
・桁数を数えるはずのdigitが、数える毎じゃなくてプログラムの最初に一度だけしか初期化されていない
n桁を越えたら止めるはずが、n+1を越えたら止めることになっている

を直せば、int型の扱える数値の範囲内では上手く行きます。普通は10桁くらいです。long long intであっても19桁くらいが限界。

投稿2020/07/29 17:16

otn

総合スコア85901

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

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

otn

2020/07/29 17:44

何乗するかは、(int)(n * log(10)/log(3)) で求まるので、あとは3のこれ乗をどうやって計算するか。 long doubleとかを使っても80桁は無理なので、工夫が要りますね。
nagano-yuhi

2020/07/31 01:45

ありがとうございます。もう一度考えてみます。
otn

2020/07/31 04:03

実用的には、多倍長計算のgmpライブラリを使うのでしょうが、今回はなんらかの課題の問題なわけで、何の課題かによって、gmpを使うのが適当なのか、課題にに沿った別のやり方をすべきなのかがわかりません。
guest

0

C

1x = x * 3; 2while (x != 0) { //xの桁数を計算 3 x = x / 10; 4 ++digit; 5}

一周目でx0にしているので、0のまま1000回ループしています。
桁数をカウントし直す際にdigitをリセットしていません。

C

1if(digit>n+1)

入力値+1桁で判定しています。

投稿2020/07/29 17:08

編集2020/07/29 17:39
SHOMI

総合スコア4079

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

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

nagano-yuhi

2020/07/31 01:46

ありがとうございます。もう一度考えてみます。
guest

0

ベストアンサー

桁数判定はxとは別の変数xtempに移してやったほうがいいと思います。
xを書き換えられると不都合なためです。
また, digitは桁数計算の前に初期化する必要があります。

intだと桁数が余裕で足りないので、long longにしました。
ですが、それでもn>18の場合にはオーバーフローして正しい答えが出ませんので、n>18の答えも正しく出したい時には多倍長整数の計算が必要になります。

C

1#include <stdio.h> 2 3int main(void) { 4 long long n; 5 scanf("%lld", &n); 6 long long x = 1LL; 7 8 for (long long i = 0; i < 1000; i++) { 9 x = x * 3LL; 10 11 long long xtemp = x; 12 long long digit = 0; 13 14 while (xtemp != 0) { // xの桁数を計算 15 xtemp /= 10LL; 16 ++digit; 17 } 18 19 if (digit > n) { 20 break; 21 } 22 } 23 printf("%lld\n", x/3LL); //最後nよりも1桁多い最小のxだから割る3 24 return 0; 25}

私の実装例

#include <assert.h> #include <stdio.h> int main(void) { long long n; scanf("%lld", &n); if (n <= 0 || n >= 18) { printf("範囲外です"); return 0; } long long end_ndigit = 1; for (long long i = 0; i < n; i++) { end_ndigit *= 10LL; } long long x = 1LL; while (x < end_ndigit) { x *= 3LL; } printf("%lld\n", x / 3LL); //最後nよりも1桁多い最小のxだから割る3 return 0; }

GNU MPで組んでみました

C

1#include <gmp.h> 2#include <stdio.h> 3 4int main(void) 5{ 6 long long n; 7 scanf("%lld", &n); 8 if(n<=0){ 9 printf("n must be positive.\n"); 10 return 0; 11 } 12 // 10**nを計算しておく 13 mpz_t end_ndigit; 14 mpz_init(end_ndigit); 15 mpz_set_ui(end_ndigit, 1); 16 for (long long i = 0; i < n; i++) { 17 mpz_mul_ui(end_ndigit, end_ndigit, 10); 18 } 19 20 // 3をかけ続け, 桁数がnを超えたら抜ける 21 mpz_t x; 22 mpz_init(x); 23 mpz_set_ui(x, 1); 24 while (mpz_cmp(x, end_ndigit) < 0) { 25 mpz_mul_ui(x, x, 3); 26 } 27 28 // 答え 29 mpz_cdiv_q_ui(x, x, 3); 30 gmp_printf("%Zd\n", x); 31 32 // 解放 33 mpz_clear(x); 34 mpz_clear(end_ndigit); 35 return 0; 36}

text

180 247780373265559358009192445772039644256794138579444188363337645975725833060824587

イメージ説明

投稿2020/07/29 17:16

編集2020/07/29 18:38
Penpen7

総合スコア698

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

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

nagano-yuhi

2020/07/31 01:44

丁寧な回答ありがとうございます!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問