【编程马拉松】【008-快到碗里来】

【编程马拉松算法目录>>>】


【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 解题思路


  题目中输入的数值比较大,所以不能使用一般的字数字进行计算,要使用大整数乘法思想。
  假设猫的长度是 mm=xi1xi2x0 ,碗的半径是 nn=xj1xj2x0 ,π取3.14。只要比较n和2*m*π的大小就可以判断猫是否可以进入碗里。因为m、n不能使用数字来表示,可以使用数组a、b来表示他们。同时因为π是小数,要将m、n、π统一成整数进行运算。可以将m放大100倍,π放大100倍。a[0]=0,a[1]=0,表示放大100倍,a[k]表示m中的 xk2 ,b[k]表示n中的 xk 。π使用数组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上进行【下载>>>】

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Github下载地址:https://github.com/XLAccount/MiaoBo 项目详解地址:http://www.code4app.com/blog-843201-350.html 快速集成RTMP的视频推流教程:http://www.code4app.com/blog-843201-315.html ffmpeg常用命令操作:http://www.code4app.com/blog-843201-326.html #关于IJKMediaFramework/IJKMediaFramework.h找不到的问题,下载后直接拉到项目中即可 下载地址:https://pan.baidu.com/s/1boPOomN 密码::9yd8 #BUG修复: 解决登录程序偶尔崩溃,修复轮播图片和页面控制器叠加等问题,修复新浪授权登录 (2016.9.7) 解决程序运行中偶尔崩溃问题,解决连续下拉刷新崩溃问题,优化代码 (2016.9.8) 优化直播页面,减少不必要的性能消耗,增加用户体验 (2016.9.11) 适配5s以上的机型除了6sPlus和6Plus延迟较大外,其余延迟都较小,网速好的话可以忽略不计 (2016.9.12) 新版本极大优化程序性能,修复关注数据异常等小问题,重新布局热门页面,减少因反复加载带来的性能消耗 (2016.9.13) 增加个人中心页面,采用下拉放大图片 ➕ 波纹效果 (2016.9.14) ![image text](https://github.com/XLAccount/ALLGIFS/blob/master/psb.gif) 展示图片 ![image](https://github.com/XLAccount/ALLGIFS/blob/master/psb-1.gif) 展示图片 ![image text](https://github.com/XLAccount/ALLGIFS/blob/master/psb-2.gif) 展示图片 ![image text](https://github.com/XLAccount/ALLGIFS/blob/master/psb-3.gif) 展示图片 感谢大神Monkey_ALin http://www.jianshu.com/users/9723687edfb5/latest_articles 的demo支持
马拉松编程题目是一种挑战性的编程竞赛,要求参赛者在有限的时间内解决一系列复杂的编程问题。这些题目旨在测试参赛者的编程技能、算法思维和解决问题的能力。 在NOI(全国青少年信息学奥林匹克竞赛)中,编程马拉松题目非常有名。参赛者通常需要在一天内完成多个编程问题,每个问题的难度和复杂性都不同。这些题目可能涉及算法数据结构、动态规划、图论等各种领域。 参赛者在比赛开始时会收到一份题目清单,然后他们需要逐个解决各个问题。解题速度和准确性是评判参赛者成绩的重要指标。因为时间有限,参赛者需要在压力下迅速找到问题的解决方法,并编写高效的代码。 编程马拉松不仅考察了参赛者的编程技能,也考验了他们的团队合作能力。许多编程马拉松都是以小组形式进行,每个小组的成员需要相互配合,合理分工,共同完成任务。 参加编程马拉松有助于提升参赛者的编程能力和解决问题的能力。通过面临各种难题和时间限制,参赛者能够锻炼自己的思维能力和解决问题的方法。此外,参加编程马拉松还能与其他优秀的编程爱好者交流、学习,扩展自己的知识和视野。 总之,编程马拉松是一种激动人心的编程竞赛,可以帮助参赛者提升编程能力和解决问题的能力。这种比赛不仅考察了编程技能,还培养了团队合作和应对压力的能力,对于对编程有兴趣的人来说是一次难得的学习和锻炼机会。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值