#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;
}
C言語 ぽ
C言語 ぽ
1000以下の数字の中で一番節が長くなる数字を見つけたいのですが上手くできず頭を悩ましています…
-UUU:----F1 gyaku3.c Top L7 (C/l Abbrev) --------------------------------------------------------------------------------------------------------------------------------------------------------
Re: C言語 ぽ
近況報告ありがとうございます。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言語 ぽ
#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)
Re: C言語 ぽ
循環節の長さが除数より小さいことを考えると、除数の大きな数から小さい数への方向へ循環節長を計算し、それまでの最大循環節長が除数より大きくなったところで打ち切ってもいいんじゃないでしょうか。
これであっているかな?
// 引数の逆数の循環節を計算する
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;
}