C言語 ぽ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
opop
記事: 1
登録日時: 1年前

C言語 ぽ

#1

投稿記事 by opop » 1年前

1000以下の数字の中で一番節が長くなる数字を見つけたいのですが上手くできず頭を悩ましています…

コード:

#include <stdio.h>
#include <stdlib.h>

int i,j;
int count=0;
int m=0,k=0,f;
int *a,*b,*c;

void zyunkan(int x,int y){
  
  a=malloc((4*y) * sizeof(int));

  b=a+y;
  c=b+y;
  a[0]=b[0]=c[0]=0;

  for(i=1;;i++){
    c[i]=x%=y; // 余りを求めて、憶えておく                                                                                                                                                                  
    j=a[x];      // 余り                                                                                                                                                                                    
    if (c[j]==x){
      break;
    }// 余りが既出なら抜ける                                                                                                                                                                                
    a[x]=i;      // 余りの位置を憶えておく                                                                                                                                                                  
    x*=10;       // 次の桁の計算に備える                                                                                                                                                                    
    b[i]=x/y;// 商を憶えておく                                                                                                                                                                              
  }


  for(j=1;j<a[x];j++){
    printf("%d", b[j]);
  }
  if (x){
    printf("(");
  }

  for(;j<i;j++){
    printf("%d", b[j]);
    count++;
  }

  if (x){
    printf(")");
  }
  if(m<count){
    m=count;
    k=y;
    printf("最も桁数が大きなる値%d\n",y);
    printf("%d\n",count);
  printf("\n");

  }

int main()
{
  int n;
  for(n=1;n<=1000;n++){
    zyunkan(1,n);
  }

  free(a);
  return 0;
}
-UUU:----F1 gyaku3.c Top L7 (C/l Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------

アバター
みけCAT
記事: 6227
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: C言語 ぽ

#2

投稿記事 by みけCAT » 1年前

opop さんが書きました:1000以下の数字の中で一番節が長くなる数字を見つけたいのですが上手くできず頭を悩ましています…
近況報告ありがとうございます。
質問はありますか?

参考:フォーラムルールより転載
「うまくいきません」という質問は大抵回答に困ります。

  1. 自分は今何がしたくて

  2. どう取り組んで(作ったプログラムはどれで

  3. どのようなエラーやトラブルで困っていて

  4. 自分は何が解らないのか、知りたいのか

  5. 今のCの知識はどの程度なのか

この5点をしっかりと明記して下さい。

環境に依存する場合やライブラリを使っているときは

使っているOS名・コンパイラ名・ライブラリ名も明記しましょう。

コンパイルエラーの質問時は必ず最低限のエラーメッセージも書きましょう
どう質問していいか解らない時は、以下のテンプレをコピペして、

各項目に対して答える形で記載して下さい。

[hr]
[1] 質問文
 [1.1] 自分が今行いたい事は何か
 [1.2] どのように取り組んだか(プログラムコードがある場合記載)
 [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
 [1.4] 今何がわからないのか、知りたいのか

[2] 環境  
 [2.1] OS : Windows, Linux等々
 [2.2] コンパイラ名 : VC++ 2008EE, Borand C++, gcc等々

[3] その他
 ・どの程度C言語を理解しているか
 ・ライブラリを使っている場合は何を使っているか

[hr]
オフトピック
「節」とは何なんでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

逆数

Re: C言語

#3

投稿記事 by 逆数 » 1年前

OS LINUX
コンパイラ gccです.
入力した整数1から1000までの整数の逆数を求める.
(例)
6の逆数 0.166666 →0.1(6)
7の逆数 0.142857142857142857 →0.(142857)

この()内の数をカウントして一番大きくなった整数を表示させるプログラムを作成したいのですが,1から1000全て表示されてしまいます.

かずま

Re: C言語 ぽ

#4

投稿記事 by かずま » 1年前

コード:

#include <stdio.h>

#define SIZE 20  // #define SIZE 1000

int pos[SIZE], quo[SIZE], rem[SIZE], count, max_y;

void recurring(int x, int y)
{
    int i = 0, j, k, z = x;
    pos[0] = rem[0] = 0;
    while (1) {
        quo[i++] = z / y;   // 商(quotient)を憶えておく
        rem[i] = z %= y;    // 余り(remainder)を求めて、憶えておく
        j = pos[z];         // 余りの位置 (ただし、未初期化の場合あり) 
        if (j >= 0 && j < i && rem[j] == z) break;  // 余りが既出なら抜ける
        pos[z] = i;         // 余りの位置(position)を憶えておく
        z *= 10;            // 次の桁の計算に備える
    }
    k = i - pos[z];         // 循環節の長さ、または循環しない場合の桁数
    if (k > count) count = k, max_y = y; // 最大の循環節が見つかった
    printf("%4d: %d/%d = %d.", k, x, y, quo[0]);
    for (j = 1; j < pos[z]; j++) printf("%d", quo[j]);
    if (z) putchar('(');
    for (; j < i; j++) printf("%d", quo[j]);
    if (z) putchar(')');
    putchar('\n');
}

int main(void)
{
    for (int n = 1; n <= SIZE; n++) recurring(1, n);
    puts("---");
    recurring(1, max_y);
    return 0;
}
実行結果

コード:

   1: 1/1 = 1.
   2: 1/2 = 0.5
   1: 1/3 = 0.(3)
   3: 1/4 = 0.25
   2: 1/5 = 0.2
   1: 1/6 = 0.1(6)
   6: 1/7 = 0.(142857)
   4: 1/8 = 0.125
   1: 1/9 = 0.(1)
   2: 1/10 = 0.1
   2: 1/11 = 0.(09)
   1: 1/12 = 0.08(3)
   6: 1/13 = 0.(076923)
   6: 1/14 = 0.0(714285)
   1: 1/15 = 0.0(6)
   5: 1/16 = 0.0625
  16: 1/17 = 0.(0588235294117647)
   1: 1/18 = 0.0(5)
  18: 1/19 = 0.(052631578947368421)
   3: 1/20 = 0.05
---
  18: 1/19 = 0.(052631578947368421)
#define SIZE 1000 では、いくつになるでしょうか?

maru
記事: 150
登録日時: 8年前

Re: C言語 ぽ

#5

投稿記事 by maru » 1年前

循環節の長さが除数より小さいことを考えると、除数の大きな数から小さい数への方向へ循環節長を計算し、それまでの最大循環節長が除数より大きくなったところで打ち切ってもいいんじゃないでしょうか。

コード:

// 引数の逆数の循環節を計算する
int recurringLength(int n, int* pRemains)
{
	int	remain = 1;
	int*	pRemain = pRemains;
	*pRemain = remain;
	while (remain)
	{
		int* p = pRemains;
		for (; p < pRemain; ++p)
		{
			if (remain == *p)
			{
				return pRemain - p;
			}
		}
		remain *= 10;
		remain %= n;
		*(++pRemain) = remain;
	}
	return 0;
}

#define N 1000

int main(int argc, char *argv[])
{
	int	maxLength = 0;
	int	number = 0;
	int	remains[N] = {0};
	for (int i = N; i > maxLength; --i)
	{
		int length = recurringLength(i, remains);
		if (maxLength < length)
		{
			maxLength = length;
			number = i;
		}
	}
	printf("%d\n", number);

	return 0;
}

コード:

983
これであっているかな?

返信

“C言語何でも質問掲示板” へ戻る