【编程马拉松】【008-快到碗里来】
2016-06-08 09:36
204 查看
【编程马拉松算法目录>>>】
【008-快到碗里来】【工程下载>>>】
1 题目描述
小喵们很喜欢把自己装进容器里的(例如碗),但是要是碗的周长比喵的身长还短,它们就进不去了。现在告诉你它们的身长,和碗的半径,请判断一下能否到碗里去。1.1 输入描述:
输入有多组数据。每组数据包含两个整数n (1≤n≤2^128) 和r (1≤r≤2^128),分别代表喵的身长和碗的半径。圆周率使用3.14。1.2 输出描述:
对应每一组数据,如果喵能装进碗里就输出“Yes”;否则输出“No”。1.3 输入例子:
6 1 7 1 9876543210 1234567890
1.4 输出例子:
Yes No No
2 解题思路
题目中输入的数值比较大,所以不能使用一般的字数字进行计算,要使用大整数乘法思想。假设猫的长度是m(m=xi−1xi−2…x0)m(m=x_{i-1} x_{i-2}…x_0),碗的半径是n(n=xj−1xj−2…x0)n(n=x_{j-1} x_{j-2}…x_0),π取3.14。只要比较n和2*m*π的大小就可以判断猫是否可以进入碗里。因为m、n不能使用数字来表示,可以使用数组a、b来表示他们。同时因为π是小数,要将m、n、π统一成整数进行运算。可以将m放大100倍,π放大100倍。a[0]=0,a[1]=0,表示放大100倍,a[k]表示m中的xk−2x_{k-2},b[k]表示n中的xkx_k。π使用数组PI表示。PI[0]=4,PI[1]=1,PI[2]=3。计算2*b*PI(结果为r)再比较r与n的大小即可。
3 算法实现
import java.util.Scanner; /** * Author: 王俊超 * Time: 2016-05-09 08:44 * CSDN: http://blog.csdn.net/derrantcm * Github: https://github.com/Wang-Jun-Chao * Declaration: All Rights Reserved !!! */ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt")); while (scanner.hasNext()) { String cat = scanner.next(); String bowl = scanner.next(); System.out.println(toTheBowl(cat, bowl)); } scanner.close(); } /** * 判断猫是否可以进到碗里 * * @param cat 猫的长度 * @param bowl 碗的半径 * @return Yes:猫可以到碗里,false:猫不可以到碗里 */ private static String toTheBowl(String cat, String bowl) { // 200*PI int[] PI = {8, 2, 6}; // cat的值要放大100倍 int[] n = new int[cat.length() + 2]; int[] m = new int[bowl.length()]; // 将cat转换成数值,并且放大100倍 for (int i = 0; i < cat.length(); i++) { n[i + 2] = cat.charAt(cat.length() - i - 1) - '0'; } // bowl转换成数值 for (int i = 0; i < bowl.length(); i++) { m[i] = bowl.charAt(bowl.length() - i - 1) - '0'; } int[] r = calculate(m, PI); if (compare(r, n) >= 0) { return "Yes"; } else { return "No"; } } /** * 比较两个整数是否相等,下标由小到大表示由低位到高位,忽略最高有效位上的前导0 * * @param m 整数 * @param n 整数 * @return m > n返回1,m = n返回0,m < n返回-1 */ private static int compare(int[] m, int[] n) { if (m == null && n == null) { return 0; } // null最小 if (m == null) { return -1; } if (n == null) { return 1; } int lastM = m.length - 1; int lastN = n.length - 1; // 找m的最高有效位的位置,至少有一位 while (lastM >= 1 && m[lastM] == 0) { lastM--; } // 找n的最高有效位的位置,至少有一位 while (lastN >= 1 && n[lastN] == 0) { lastN--; } // m的数位比n多,说明m比n大 if (lastM > lastN) { return 1; } // m的数位比n少,说明m比n小 else if (lastM < lastN) { return -1; } else { // 位数一样,比较每一个数位上的值,从高位到低位进行比较 for (int i = lastM; i >= 0; i--) { if (m[i] > n[i]) { return 1; } else if (m[i] < n[i]) { return -1; } } return 0; } } /** * 两个数相乘 * * @param m 乘数 * @param n 乘数 * @return 结果 */ private static int[] calculate(int[] m, int[] n) { if (n == null || n.length < 1 || m == null || m.length < 1) { return null; } // 结果最多的位数 int[] r = new int[m.length + n.length]; // 来自低位的进位 int c; int t; int k; for (int i = 0; i < n.length; i++) { // 计算n[i]*m if (n[i] == 0) { continue; } c = 0; for (int j = 0; j < m.length; j++) { t = n[i] * m[j] + r[i + j] + c; r[i + j] = t % 10; c = t / 10; } // 如果还有进位要继续处理 k = i + m.length; while (c != 0) { t = c + r[k]; r[k] = t % 10; c = t / 10; k++; } } return r; } }
4 测试结果
5 其它信息
因为markddow不好编辑,因此将文档的图片上传以供阅读。Pdf和Word文档可以在Github上进行【下载>>>】。相关文章推荐
- php startup:unable to load dynamic openssl
- matlab GUI之常用对话框(一)-- uigetfile\ uiputfile \ uisetcolor \ uisetfont
- springmvc 学习(一)
- python安装ez_setup.py 【windows环境】
- Python while 循环使用实例
- Python数据类型转换
- Java泛型
- Qt里怎么处理二进制数据
- C语言: fwrite和fread函数的用法小结 (网上摘抄,方便以后查询)
- java.sql.SQLException: ORA-01000: 超出打开游标的最大数
- 使用jdk自带的线程池。加载10个线程。
- ssh环境搭建(1)-lib篇(spring4.2.6+struts2.5+hibernate5.1 )
- java之volatile关键字学习
- java设计模式--工厂模式学习之使用…
- java POI读取excel
- 关于java读取properties文件的路径…
- Java、JDBC与MySQL数据类型对照
- java 嵌套类总结
- java中的嵌套类
- Java中正则Matcher类的matches()、…