算法习题---3.08循环小数(UVa202)
一:题目
输入整数a和b(<=a<=,<=b<=),输出a/b的循环小数表示以及循环节长度。 例如,a=,b=,小数表示为0.(),循环字节长度为21

当循环节长度超过50时,后面使用...代替,不进行输出后面部分
(一)样例输入
(二)样例输出
/ = 3.04()
= number of digits in repeating cycle
/ = .()
= number of digits in repeating cycle
/ = .(...)
= number of digits in repeating cycle
二:题目分析
(一)余数用作判断循环节的依据:(循环节长度大小不会超过余数大小,原因如下:)
/-->/=...
/-->/=...4出现两次4,所以一定会出现循环节
/-->/=...4出现三次4,所以循环节就在二三次之间(即商6)
所以用一个数组记录余数,大小不会超过除数大小
(二)同时也要记录商,用于记录循环节
若是除数为P,则余数为0->P-1;所以在P次之间一定会出现两个相同余数 //(一中原因)
-->一定会出现循环节
所以我们再记录一次余数,当出现某个余数出现为3次,那么循环节在两个余数位置中间
由于商数组和余数数组对应,所以可以轻松找到循环节
(三)商数组和余数数组大小
余数数组大小应该为除数大小 //余数只需要除数大小,用于记录余数出现次数
商数组大小应该为除数大小的两倍 //商用于记录对应余数中的商值,由于每一个余数必须出现3次,所以我们记录的商必须足够长,足以支持余数次数到达3
例:
其中0<=a<=,<=b<=--->
所以余数数组不会超过3000 商数组大小不超过6000
注:上面的商和余数数组只记录小数点后的值,不记录整数值
三:代码分析(使用76/25 ,1/6 ,5/43分析)
(一)处理整数部分:只剩下会出现小数部分的被除数进行下一步处理
//开始处理数据
//1.获取整数
//先记录整数:可以在记录时直接输出,节省篇幅
printf("%d/%d = ", a, b);
if (!(a / b))
printf("");
else
while (a / b)
{
printf("%d", a / b);
a %= b;
}
printf(".");
(1)76/25
/=...
代码输出76/25 = 3.
(2)1/6
直接为小数,所以按照代码输出1/6 = 0.
(3)5/43
直接为小数,所以按照代码输出5/43 = 0.
(二)获取商数组和余数数组
//2.开始记录商和余数
i = ;
while () //例如:1/6
{
//记录商和余数
res[i] = a * 10 / b; //10/6=1 //1.记录商
rem[a * 10 % b]++; //10%6=4 //2.记录对应余数位置出现次数 //注意两次和三次都是只记录一次即可
if (rem[a * 10 % b] == 2&&!two_flag) //3.若是出现两次,则开始进行记录 只记录第一个出现两次的余数
{
r_s = i;
two_flag = ;
}
if (rem[a * 10 % b] == 3) //4.若是出现3次,则确定了循环节位置,直接跳出
{
r_e = i;
break;
}
//处理被除数
a = a * % b; //a = 4
i++;
}
(1)76/25
/=... 0 1 第一个为商下标,第二个为余数次数
/=... 1 1
/=... 2 2 余数出现两次时的商0和出现一次时的商4不一致
/=... 3 3
res = { }
rem = { }
(2)1/6
/=... 0 1 第一个为商下标,第二个为余数次数
/=... 1 2 余数出现两次时的商6和出现一次时的商1不一致
/=... 2 3
res = { }
rem = { }
(3)5/43
/=... 0 1
/=... ...
.....=... 21 2 余数出现两次时的商和出现一次时的商一致 ...
.....=... 42 3
(三):进行数据输出
注意记录数据时要区分0.() 3.04() 和0.(....)
不同之处在于循环节是不是从小数第一位开始
处理原则在于看1,2两次余数相同时,商是否一致(上面案例)
int rep_count = r_s;
if (res[r_s] != res[2 * r_s - r_e]) //若是余数第一次和第二次对应的商值不一样,则加一
rep_count++; for (j = ; j <rep_count ;j++) //注意,先看下面注释,可以知道,真正循环节结束在我们获取的第二个相同余数位置-->即r_s
{
if (j == * r_s - r_e && rep_count==r_s) //注意这里:不是j-r_s
printf("(");
else if (j == * r_s - r_e+&&rep_count==r_s+) //遇到循环节不是从小数点后开始,则向后一位
printf("(");
printf("%d", res[j]);
if (j +r_e- *r_s == ) //不是j-r_s -->因为我们虽然确定r_s到r_e时一个循环节,但是r_s是第二个相同余数开始,r_e是第三个余数开始
{ //4 4 4--->r_s是第二个开始,r_e是第三个开始,但是真的循环节是从第一个4到第二个4
printf("...");
break;
}
} printf(")\n");
printf(" %d = number of digits in repeating cycle\n", r_e - r_s);
四:代码实现
void test33()
{
int a, b;
int zs[]; //存放整数,例如结果10.13161616,这里用于存放10
//由于程序变更,后面没有用到zs,但是为了便于理解,留在这
int res[MAX_REP]; //存放商
int rem[MAX_REP]; //存放余数 int two_flag; //注意两次和三次都是只记录一次即可,但是由于三次直接break,所以不做标志 int i, j;
int r_s, r_e; //循环节开始,循环节结束 FILE* fi = freopen("data2.in", "r", stdin);
freopen("data2.out", "w", stdout); while (!feof(fi))
{
scanf("%d", &a);
scanf("%d", &b); memset(zs, , sizeof(zs));
memset(res, , sizeof(res));
memset(rem, , sizeof(rem)); two_flag = ; //开始处理数据
//1.获取整数
//先记录整数:可以在记录时直接输出,节省篇幅
printf("%d/%d = ", a, b);
if (!(a / b))
printf("");
else
while (a / b)
{
printf("%d", a / b);
a %= b;
}
printf("."); //2.开始记录商和余数
i = ;
while () //例如:1/6
{
//记录商和余数
res[i] = a * / b; //10/6=1
rem[a * % b]++; //10%6=4 //注意两次和三次都是只记录一次即可
if (rem[a * % b] == &&!two_flag) //若是出现两次,则开始进行记录
{
r_s = i;
two_flag = ;
}
if (rem[a * % b] == )
{
r_e = i;
break;
}
//处理被除数
a = a * % b; //a = 4
i++;
} //开始记录数据
//注意记录数据时要区分0.1(6) 3.04(0) 和0.(11....)
//不同之处在于循环节是不是从小数第一位开始
//处理原则在于看1,2两次余数相同时,商是否一致
int rep_count = r_s;
if (res[r_s] != res[ * r_s - r_e])
rep_count++; for (j = ; j <rep_count ;j++) //注意,先看下面注释,可以知道,真正循环节结束在我们获取的第二个相同余数位置-->即r_s
{
if (j == * r_s - r_e && rep_count==r_s) //注意这里:不是j-r_s
printf("(");
else if (j == * r_s - r_e+&&rep_count==r_s+) //遇到循环节不是从小数点后开始,则向后一位
printf("(");
printf("%d", res[j]);
if (j +r_e- *r_s == ) //不是j-r_s -->因为我们虽然确定r_s到r_e时一个循环节,但是r_s是第二个相同余数开始,r_e是第三个余数开始
{ //4 4 4--->r_s是第二个开始,r_e是第三个开始,但是真的循环节是从第一个4到第二个4
printf("...");
break;
}
} printf(")\n");
printf(" %d = number of digits in repeating cycle\n", r_e - r_s);
} freopen("CON", "r", stdin);
freopen("CON", "w", stdout);
}
算法习题---3.08循环小数(UVa202)的更多相关文章
- 【算法习题】数组中任意2个(3个)数的和为sum的组合
题1.给定一个int数组,一个数sum,求数组中和为sum的任意2个数的组合 @Test public void test_find2() { int[] arr = { -1, 0, 2, 3, 4 ...
- 循环小数 UVa202
输入整数a和b(0<=a<=3000,1<=b<=3000),输出a/b的循环小数表示以及循环节长度. 例如,a=5,b=43,小数表示为0.(1162790697674418 ...
- July 算法习题 - 字符串4(全排列和全组合)
https://segmentfault.com/a/1190000002710424 思想:当前层各节点首元素不同,则各节点的剩余元素也不同:下一层节点交换范围为首元素以外的元素 全排列算法: vo ...
- 算法习题---4-9数据挖掘(Uva1591)
一:题目 这是最懵逼的一道题,什么鬼......... [刷题]算法竞赛入门经典(第2版) 4-9/UVa1591 - Data Mining(详细题目看这个吧,不想多说) 二:代码实现 #defin ...
- tarjan算法 习题
dfs树与tarjan算法 标签(空格分隔): 517coding problem solution dfs树 tarjan Task 1 给出一幅无向图\(G\),在其中给出一个dfs树\(T\), ...
- 【算法习题】正整数数组中和为sum的任意个数的组合数
1.递归实现(参考:https://blog.csdn.net/hit_lk/article/details/53967627) public class Test { @org.junit.Test ...
- 算法习题-FFT
Q1(hdu1402): 给出两个很大的数字A,B,计算二者乘积. 分析:这个题目java应该能过,用FFT做能够加速计算.这里将字符串A按权(10进制)展开,前面的系数就是多项式的系数,这样就构造出 ...
- 笔试算法题(08):输出倒数第K个节点
出题:输入一个单向链表,要求输出链表中倒数第K个节点 分析:利用等差指针,指针A先行K步,然后指针B从链表头与A同步前进,当A到达链表尾时B指向的节点就是倒数第K个节点: 解题: struct Nod ...
- 算法习题---5-8图书管理系统*****<双向迭代器>(UVa230)
一:题目 就是输入一系列书本名和作者名,然后输入命令模拟借书和还书,再输出归还的书的摆放位置.要求有两点: 需要对归还的书做特殊排序处理:作者名相同,则书本按书名从小到大排序:否则书本按作者名大小排序 ...
随机推荐
- Django之路——2 Django的安装
Django的安装分为两种方式,一种是命令行安装,另外一种是pycharm安装.在这里只说一种在命令行里面安装的 1.命令行安装 这个自不必多说,直接上干货,如果遇到pip版本过低,安装失败的,请自自 ...
- HTTP请求响应过程以及与HTTPS区别
HTTP协议 HTTP协议主要应用是在服务器和客户端之间,客户端接受超文本. 服务器按照一定规则,发送到客户端(一般是浏览器)的传送通信协议.与之类似的还有文件传送协议(file transfer p ...
- Java原子类--AtomicLong
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3514593.html AtomicLong介绍和函数列表 AtomicLong是作用是对长整形进行原子操 ...
- redis 发展史 应用场景
引言 在Web应用发展的初期,那时关系型数据库受到了较为广泛的关注和应用, 原因是因为那时候Web站点基本上访问和并发不高.交互也较少. 而在后来,随着访问量的提升,使用关系型数据库的Web站点多多少 ...
- BZOJ 1495 [NOI2006]网络收费(暴力DP)
题意 给定一棵满二叉树,每个叶节点有一个状态0/10/10/1,对于每两个叶节点i,ji,ji,j,如果这两个叶节点状态相同但他们的LCALCALCA所管辖的子树中的与他们状态相同的叶节点个数较少(少 ...
- bootstrap最简单的导航条
<nav class="navbar navbar-default navbar-static-top"> <div class="navbar-hea ...
- Airtest真机链接(一)
确认ADB是否能够正常连接到手机 windows系统下: 用USB线连好手机后,进入AirtestIDE文件夹,在 AirtestIDE_2019-05-09_py3_win64/airtest/co ...
- React重置非受控组件state的方法
如果想通过props来重置state的值.有3种方法: 1. 最好的方法:key属性 修改key属性的值,可以使组件卸载后重新加载.所有的状态全部重置. 这种情况可以给key设一个每次渲染都会改变的值 ...
- VSCodeUserSetup安装教程
VSCodeUserSetup: isual Studio Code是一个轻量级但功能强大的源代码编辑器,可在桌面上运行,适用于Windows,macOS和Linux.它内置了对JavaScript, ...
- MAC OS系统替换homebrew使用阿里云的镜像源
MAC OS系统替换homebrew使用阿里云的镜像源 2019-03-03 15:13:42 南通SEO 阅读数 2024更多 分类专栏: 解决方案 MAC OS系统替换homebrew使用阿里 ...