【POJ】3720 Occurrence of Digits

本文详细介绍了使用C语言进行POJ题目3720OccurrenceofDigits的解决方法,通过将分数转换为无限循环小数来统计特定数字的出现次数。包含代码实现与实例解析。

感觉太久没写C代码了,打算以后有事没事就去做一做POJ,既能写代码练练手,又能提高我这弱弱的算法的能力,还能开拓思维……好处不多说啦,差点能包治百病偷笑


今天做的是3720 Occurrence of Digits:

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 (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



内容概要:本文档是一份关于交换路由配置的学习笔记,系统地介绍了网络设备的远程管理、交换机与路由器的核心配置技术。内容涵盖Telnet、SSH、Console三种远程控制方式的配置方法;详细讲解了VLAN划分原理及Access、Trunk、Hybrid端口的工作机制,以及端口镜像、端口汇聚、端口隔离等交换技术;深入解析了STP、MSTP、RSTP生成树协议的作用与配置步骤;在路由部分,涵盖了IP地址配置、DHCP服务部署(接口池与全局池)、NAT转换(静态与动态)、静态路由、RIP与OSPF动态路由协议的配置,并介绍了策略路由和ACL访问控制列表的应用;最后简要说明了华为防火墙的安全区域划分与基本安全策略配置。; 适合人群:具备一定网络基础知识,从事网络工程、运维或相关技术岗位1-3年的技术人员,以及准备参加HCIA/CCNA等认证考试的学习者。; 使用场景及目标:①掌握企业网络中常见的交换与路由配置技能,提升实际操作能力;②理解VLAN、STP、OSPF、NAT、ACL等核心技术原理并能独立完成中小型网络搭建与调试;③通过命令示例熟悉华为设备CLI配置逻辑,为项目实施和故障排查提供参考。; 阅读建议:此笔记以实用配置为主,建议结合模拟器(如eNSP或Packet Tracer)动手实践每一条命令,对照拓扑理解数据流向,重点关注VLAN间通信、路由选择机制、安全策略控制等关键环节,并注意不同设备型号间的命令差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值