感觉太久没写C代码了,打算以后有事没事就去做一做POJ,既能写代码练练手,又能提高我这弱弱的算法的能力,还能开拓思维……好处不多说啦,差点能包治百病
Description
Every fraction can be converted to a repeatin decimal. For example 1/2 = .5, 1/3 = .(3) and 1/6 = .1(6). Given an integer n, Tom wants to know how many digit k occurs totally in the repeating decimal presentation of 1/2, 1/3 ... 1/n.
Input
The input consists of several test cases. Each test case is a line containing two integers n (2 ≤ n ≤ 100) and k (0 ≤ k ≤ 9).
Output
Output the total occurrence of the digit.
Sample Input
3 5 7 3 7 0
Sample Output
1 1 0
该题主要是考查如何将分数转为无限循环小数的算法,在统计数字的出现频率则解决问题:
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 128
/* 1/n(n >= 2) to repeating decimal, save in resultStr*/
int Frac2RepDec(int n, char *resultStr, int size)
{
if (size < 2)
{
fprintf(stderr, "resultStr size is too small.");
return 0;
}
else if (n == 1)
{
strcpy(resultStr, "1");
return 1;
}
int mark[n * 10];
int index[n * 10];
char result[BUFFER_SIZE];
memset(mark, 0, sizeof(mark));
memset(index, -1, sizeof(index));
memset(result, 0, sizeof(result));
int i = 0, t = 10, startIndex = -1;
int remainder = 0;
while (1)
{
remainder = t % n;
if (remainder == 0)
{
result[i++] = t / n + 48; // 转为ascii码数字
break;
}
else if (mark[t])
{
startIndex = index[t];
break;
}
mark[t] = 1;
index[t] = i;
result[i++] = t / n + 48; // 转为ascii码数字
t = remainder * 10;
}
char temp[BUFFER_SIZE];
int j = 0;
temp[j++] = '.';
for (i=0; result[i]>=48; ++i)
{
if (i == startIndex)
temp[j++] = '(';
temp[j++] = result[i];
}
if (startIndex >= 0)
temp[j++] = ')';
temp[j++] = 0;
if (size < strlen(temp))
{
fprintf(stderr, "resultStr size is too small.");
return 0;
}
else
{
strcpy(resultStr, temp);
return 1;
}
}
int main()
{
char resultStr[BUFFER_SIZE];
int count[10];
int n, digit;
int i, j;
while (scanf("%d%d", &n, &digit) != EOF)
{
memset(count, 0, sizeof(count));
for (i=2; i<=n; ++i)
{
if (Frac2RepDec(i, resultStr, BUFFER_SIZE))
{
//printf("%d/%d = %s\n", 1, i, resultStr);
for (j=0; j<strlen(resultStr); ++j)
if (isdigit(resultStr[j]))
{
++count[resultStr[j] - 48];
}
}
}
printf("%d\n", count[digit]);
}
return 0;
}
Frac2RepDec函数输出的字符串格式如下所示(1/2 , 1/3...1/20的无限循环小数):
1/2 = .5
1/3 = .(3)
1/4 = .25
1/5 = .2
1/6 = .1(6)
1/7 = .(142857)
1/8 = .125
1/9 = .(1)
1/10 = .1
1/11 = .(09)
1/12 = .08(3)
1/13 = .(076923)
1/14 = .0(714285)
1/15 = .0(6)
1/16 = .0625
1/17 = .(0588235294117647)
1/18 = .0(5)
1/19 = .(052631578947368421)
1/20 = .05