• UVA-202 Repeating Decimals


    /* http://blog.csdn.net/mobius_strip/article/details/39870555
      这题涉及到了抽屉原理,也叫鸽巢原理,有时间不妨看看,我下载了相关文档
      http://www.xuebuyuan.com/2224752.html
      这个blog讲解得比较细致易懂,但是它的代码是RE的,不过思路和下面那串代码也是大同小异的,就没有改代码了
      
      这题和一般的除法处理也很类似:不断被除数除以除数,商放入数组以备输出,余数(先保存,后面解释原因)*10作为新的被除数,再去得到除数...依次类推
      
      为什么保存余数?
      按照上面的描述,以及除法的规则,我们可以发现,只要在不断更新过程中,出现了之前出现过的余数,则循环节找到了,因为此后,就是这个相等的余数*10/被除数作商,取模被除数作余数,循环往复,关键还是找规律,发现结合除法的规则,这种情况,刚好就是找到了循环节的情况
      
      可能用抽屉原理以后,理解这个会更快,不过目前也能想明白
      
      此外,注意下左括号输出的条件,是在 i到min(50, cnt-1)之间,是否满足最后留下的a,所对应的位置flag[a]是等于i的,这点一定要想明白
      
      又及,既然i从1开始,那么第一个余数,就应该是flag[a % b] = 1;(a和b没变化前),但那时对于q的处理,我们却是q[0] = a / b; 这就说明,在我的代码中,q数组并不和 r数组和flag数组,一一同步变化...这点一定一定要小心,当初就是一直错了这里,没有转过弯来
      
      再次说明flag[i]== j意味着,在第j此做除法时,得到的余数时i,如果发现flag[i]不为0,说明前面的除法中,已经出现了余数为i的情况,也就意味着,找到了循环节
      
      最后,这题的格式,又忘记格式控制了,耐心细致!WA使人崩溃,但如果时PE的话,真的十分可惜,尽量减少罚时
    */
    
    #include <iostream>
    #include <cstring>
    //#include <bits/stdc++.h>
    using namespace std;
    const int N = 5000; //注意数组不可开太小,否则RE
    int q[N],  flag[N]; //三个数组分别对应商、余数,记录某个余数对应是在flag数组哪位出现,标记是否找到循环节,何处找到 
    
    int main()
    {
    	int a, b, cnt;
    	while (cin >> a >> b)
    	{
    		int tp = a;
    		memset(flag, 0, sizeof(flag));
    		q[0] = a / b;
    		a %= b;
    		for (cnt = 1; a && !flag[a]; cnt++) // 退出这层循环,可能是因为余数为0了,也有可能是因为找到了循环节 
    		{
    			flag[a] = cnt;
    			q[cnt] = a * 10 / b;
    			a = a * 10 % b;// 很符合我们除法的规律,将余数*10再除以除数得商
    		}
    		
    //		for (int i = 0; i < cnt; i++) cout << q[i] << " ";
    	
    		cout << tp << "/" << b << " = " << q[0] << ".";
    		//注意这几个 if-else 的出场顺序十分重要,有些虽然最后n为0,但不可以一开始就输出 (0,例如这组数据 76 25
    		
    		for (int i = 1; i < cnt && i <= 50; i++)
    		{
    			if (a && flag[a] == i) //整除的情况后面有分支单独处理,此步考虑有循环节的情况,且此句对应着,现在就是碰到了循环节
    			cout << "(";
    			cout << q[i]; 
    		} 
    		if (!a) cout << "(0";
    		if (cnt > 50) cout << "...";
    		cout << ")" << endl;
    		
    	//	cout << "test: " << a << " " << flag[a] << endl;
    		cout << "   " << (!a?1:cnt - flag[a]) << " = number of digits in repeating cycle" << endl << endl;
    		//flag[a]找对应余数为a的位置 
    	}
    	return 0;
    }

  • 相关阅读:
    eCryptfs文件系统测试
    体验企业级网络管理软件(图片加视频)
    基于Linux2.6内核的加密容器法保护文件方法
    Orion Network Performance Monitor 软件在网络管理中的应用
    两款硬件代理服务器产品之比较
    3Com Network Supervisor与IBM Tivoli NetView两款网管软件操作视频
    成为IBM精英讲师-一分耕耘 一份收获 同时也多了一份责任!
    Hp Open View安装使用视频
    在Fedora 14 alpha 下测试Kvm情况(视频)
    ACM模板——分数类
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789546.html
Copyright © 2020-2023  润新知