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


【011-鸽兔同校】【工程下载>>>】


1 题目描述


  浙江大学校园里绿树成荫,环境非常舒适,因此也引来一批动物朋友来此居住。
  童心未泯的NowCoder就经常带些碎面包什么的去广场喂鸽子和兔子,并和它们玩耍。 一点也没有大学生的样子,还是一副老不正经的样子,呵呵。
  随着鸽子和兔子数目的增多,NowCoder带的那点食物已经不够它们瓜分了。为了能让自己的好朋友吃的饱饱的, NowCoder决定统计一下有多少只鸽子和有多少只兔子,以便带来足够的食物。一、二、三、四、五…他开始数了。
  现在,他已经知道有这些鸽子和兔子一共有n个头和m只脚。请你帮他写个程序计算一下一共有多少只鸽子和兔子。

1.1 输入描述:


  输入包括多组数据。
  每行包括2个正整数n和m,n和m可能会很大,超过2^64,但位数不超过100位。

1.2 输出描述:


  每组数据的输出都只有一行,分别是鸽子的数量和兔子数量。
  如果输入的测试数据不能求得结果,那肯定是NowCoder这个马大哈数错了,就输出“Error”提示他。

1.3 输入例子:


35 94
1 3

1.4 输出例子:


23 12
Error

2 解题思路


  假设有x只鸽子,y只兔子,它们的头和脚的数目分别是m和n。则有:

{x+y=m2x+4y=n⟺{x=4m−n2y=n−2m2x∈Ny∈N 

\begin{cases} x+y=m \\ 2x+4y=n \end{cases} \iff \begin{cases} x=\frac{4m-n}{2}&x∈{\rm N} \\ y=\frac{n-2m}{2}&y∈{\rm N}\ \end{cases}

  x和y都是自然数⇒n为偶数,x=4m−n2⇒4m−nx=\frac{4m-n}{2}⇒4m-n为偶数(一定成立,因为n为偶数),y=n−2m2⇒n−2my=\frac{n-2m}{2}⇒n-2m为偶数(一定成立,因为n为偶数)。同时因为m和n非常大,要使用大整数进行操作。

3 算法实现

import java.util.Scanner;/*** Author: 王俊超* Time: 2016-05-09 13:55* 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 m = scanner.next();String n = scanner.next();String[] r = pigeonAndRabbit(m, n);if (r == null) {System.out.println("Error");} else {System.out.println(r[0] + " " + r[1]);}}scanner.close();}/*** 计算鸽子和兔子的数目** @param ms 鸽子和兔子的头数* @param ns 鸽子和兔子的脚数* @return 长度为2的数符串,分别表示鸽子的数量和兔子数量,如果无解就返回null*/private static String[] pigeonAndRabbit(String ms, String ns) {int lastN = ns.charAt(ns.length() - 1) - '0';// ns为偶数if (lastN % 2 != 0) {return null;}int[] m = getNumber(ms);int[] n = getNumber(ns);// 鸽子数// 4 * mint[] x = multiply(m, new int[]{4});// 兔子数// 2 * mint[] y = multiply(m, new int[]{2});// 4m >= n && n >= 2mif (compare(x, n) >= 0 && compare(n, y) >= 0) {// 4m - nx = minus(x, n);// (4m - n) / 2x = divide2(x);// n - 2my = minus(n, y);// (n - 2m) / 2y = divide2(y);return new String[]{toNumber(x), toNumber(y)};} else {return null;}}/*** 将整数字符串表示成整数数组** @param n 整数字符串* @return 整数数组 下标从小到大表示数位的从低到高*/private static int[] getNumber(String n) {int[] r = new int[n.length()];for (int i = 0; i < r.length; i++) {r[i] = n.charAt(n.length() - i - 1) - '0';}return r;}/*** 两个数相乘** @param m 乘数* @param n 乘数* @return 结果*/private static int[] multiply(int[] m, int[] n) {// 结果最多的位数int[] r = new int[m.length + n.length];// 来自低位的进位int c;int t;int k;for (int i = 0; i < n.length; i++) {// 计算n[i]*mif (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;}/*** 两个整数相加** @param m 整数* @param n 整数* @return 结果*/private static int[] add(int[] m, int[] n) {// 保证n不小于mif (m.length > n.length) {int[] t = m;m = n;n = t;}// 结果的最大长度int[] r = new int[n.length + 1];// 来自低位的进位int c = 0;for (int i = 0; i < m.length; i++) {r[i] = m[i] + n[i] + c;c = r[i] / 10;r[i] %= 10;}// 计算余下的部分for (int i = m.length; i < n.length; i++) {r[i] = n[i] + c;c = r[i] / 10;r[i] %= 10;}// 最后还有进位if (c != 0) {r[r.length - 1] = c;return r;}// 没有进位else {int[] ret = new int[r.length - 1];System.arraycopy(r, 0, ret, 0, ret.length);return ret;}}/*** 比较两个整数是否相等,下标由小到大表示由低位到高位,忽略最高有效位上的前导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;}}/*** 做减法n-m,保证n大于等于m** @param n 整数* @param m 整数* @return 结果*/private static int[] minus(int[] n, int[] m) {n = format(n);m = format(m);int[] r = new int[n.length];// 当前位被借位int c = 0;int t;for (int i = 0; i < m.length; i++) {t = n[i] - c - m[i];// 当前位够减if (t >= 0) {r[i] = t;// 没有进行借位c = 0;}// 不够减else {r[i] = t + 10;// 进行借位c = 1;}}// 还有借位for (int i = m.length; c != 0 && i < n.length; i++) {t = n[i] - c;// 当前位够减if (t >= 0) {r[i] = t;// 没有进行借位c = 0;}// 不够减else {r[i] = t + 10;// 进行借位c = 1;}}return format(r);}/*** 将整数进行格式化,去掉高位的前导0** @param r 整数* @return 结果*/private static int[] format(int[] r) {int t = r.length - 1;// 找最高有效位while (t > 0 && r[t] == 0) {t--;}int[] nr = new int[t + 1];System.arraycopy(r, 0, nr, 0, nr.length);return nr;}/*** 将数n除以2** @param n 整数* @return 结果*/private static int[] divide2(int[] n) {// 结果int[] r = new int[n.length];// 上一位除以2后的余数int c = 0;int t;for (int i = n.length - 1; i >= 0; i--) {t = c * 10 + n[i];r[i] = t / 2;c = t % 2;}return format(r);}/*** 将数组表示的整数转换成字符串** @param r 整数* @return 字符串表示的整数*/private static String toNumber(int[] r) {if (r == null) {return null;}StringBuilder b = new StringBuilder(r.length);for (int i = r.length - 1; i >= 0; i--) {b.append(r[i]);}return b.toString();}
}

4 测试结果


5 其它信息


因为markddow不好编辑,因此将文档的图片上传以供阅读。Pdf和Word文档可以在Github上进行【下载>>>】。

【编程马拉松】【011-鸽兔同校】相关推荐

  1. 牛客网编程练习之编程马拉松:鸽兔同校

    题目描述 浙江大学校园里绿树成荫,环境非常舒适,因此也引来一批动物朋友来此居住. 童心未泯的NowCoder就经常带些碎面包什么的去广场喂鸽子和兔子,并和它们玩耍. 一点也没有大学生的样子,还是一副老 ...

  2. 近期活动盘点: Call for Code编程马拉松邀请赛

    想知道近期有什么最新活动?大数点为你整理的近期活动信息在此: 关于代码行动 "代码行动"(Call for Code)是IBM联合Linux基金会.红十字会等组织发起的一项为期5年 ...

  3. 报名 | 赢取20万美金!Call For Code编程马拉松北京站来袭!

    你想通过技术改变未来的世界,并挽救生命吗? 你想组织小伙伴一同参赛,并获得20万美金吗? 你想和全球专业的开发者一同开发,并学习最前沿的AI.IoT等技术吗? 如果你内心中的答案是肯定的话...... ...

  4. 编程马拉松大赛试题及代码(C++实现)

    前段时间牛客网举办了编程马拉松大赛,总共86道题,20天内完毕. 题目难度难中易都有.我发现这些题目,主要关注性能和思维. 非常多题目用常规方法是不能通过时间要求的.题目是来自于各大oj以及面试题.所 ...

  5. C语言程序设计之编程求鸡和兔的只数,用穷举法解决

    CSDN论坛上网友的问题:有一群鸡和一群兔,两种动物只数相同.两种动物的脚的总数都是三位数,且这两个三位数的六个数字分别是0,1,2,3,4,5.编程求鸡和兔的只数是多少?它们的脚数各是多少? C语言 ...

  6. 阿里云开源编程马拉松入围项目

    在9月8号启动的 阿里云开源编程马拉松 至今已经吸引了100多个团队参赛.经过评委的初步筛选现有14个参赛项目入选.入选的项目团队/个人 将会在10月14日云栖大会现场进行路演,在大会现场颁奖并评选出 ...

  7. 核桃编程学python吗_学编程要趁早?对话核桃编程X支付宝 “小程序编程马拉松”三强得主...

    原标题:学编程要趁早?对话核桃编程X支付宝 "小程序编程马拉松"三强得主 来源:网络 浏览专业IT技术社区网站,创作沉浸式互动体验游戏,开发辟谣小程序......这并不是程序员大神 ...

  8. 编程马拉松(英语:hackathon,又译为黑客松)

    编程马拉松(英语:hackathon,又译为黑客松),又称黑客日(hack day).黑客节(hackfest)或编程节(codefest),是一个流传于黑客(hacker)当中的新词汇.编程马拉松是 ...

  9. SDCC软件开发者大会:编程马拉松团队火热招募中

    程序人生,共同成长.本次SDCC大会 Coding for Fun 编程马拉松活动即将于9月8日举行,为期一天.活动期间,开发者们共聚一堂,在32个小时里自由组队,进行产品策划和研发. 编程马拉松这个 ...

  10. 利用Python语言编程,解决鸡兔同笼问题,已知同一个笼子里鸡和兔总共有h只,鸡和兔的脚数总共有f只,其中h和f需要用户输入,求鸡和兔各有多少只。

    利用Python语言编程,解决鸡兔同笼问题,已知同一个笼子里鸡和兔总共有h只,鸡和兔的脚数总共有f只,其中h和f需要用户输入,求鸡和兔各有多少只. 提示:利用循环,采用枚举法. 要求:当输入的h和f没 ...

最新文章

  1. cocos2dx 优化略记
  2. Nature:依靠锰的氧化实现细菌的化能自养生长
  3. 开源一个ShellCode生成框架
  4. 过程化技术:打造「开放世界」的秘密
  5. 程序员建议(忘记从哪里转的了,反正是csdn上的一个兄弟)
  6. vs点击方法跳不到对于的地方_NBA总决赛G4直播:湖人vs热火,热火继续针对浓眉,能否扳平比分?...
  7. 工作70:验证放在直接父级
  8. LeetCode 1695. 删除子数组的最大得分(前缀和+哈希+双指针)
  9. 什么是编程语言,大神教你为什么要学C语言?
  10. 文件不能超过200k_为什么答题时上传的文件大小不允许
  11. [java/初学者] 猜测随机数字的大小
  12. HPS是什么?包括哪些内容?
  13. 10000小时后,我从外包走进了字节跳动
  14. python人民币和美元转换
  15. 基本知识 100118
  16. 解决Vue.directives is not a function报错
  17. [Python中的除法、除法取整、除法取余] [运算符分别为:/、//、%]
  18. Java PDF数字签名(一) - 添加数字签名
  19. selenium+python模拟浏览器进入好友QQ空间留言
  20. 软件测试入坑建议!!!

热门文章

  1. 175个常用诗词语句出处
  2. 王道数据结构3.2.5——1、循环队列中设置tag区分头指针front和队尾指针rear相等时队列的状态是空还是满
  3. DlhSoft Kanban,WPF 的看板组件
  4. 电商项目之环信在线客服接入
  5. 1个钟是多久_一个时辰是多久,一个时辰是几个小时?
  6. 迁移学习在金融行业的应用探索
  7. ibm的主要竞争对手_IBM如何计划在云中竞争
  8. 【个人代码及思路】2018年9月CSP第一题:卖菜
  9. 【开源】思源笔记自动备份
  10. 利用html2canvas和vue-qr生成带头像二维码的分享海报(二)