请用数字填空,使正面十句话都正确,用java找出答案
2016-06-04 12:06
537 查看
问题:请用数字填空,使正面十句话都正确
0在这十句话里出现的次数是______1在这十句话里出现的次数是______
2在这十句话里出现的次数是______
3在这十句话里出现的次数是______
4在这十句话里出现的次数是______
5在这十句话里出现的次数是______
6在这十句话里出现的次数是______
7在这十句话里出现的次数是______
8在这十句话里出现的次数是______
9在这十句话里出现的次数是______
题目分析:
这十句话里统计的都是数字,将每句话前面已知的数字可以提取出字符串"0123456789";同理,后面次数的10个数字也提取出一个未知的字符串"??????????";
然后将两个字符串0-9的出现的次数统计出来跟后面次数比较得出答案;
解题步骤:
由于第一个字符串得知0-9每个数字最少出现了1次;所有数字出现次数总和是20次(已经知数字10个+未知数字10个),最多不超过21次(其中某个数字可能超过9次);
单个数字不超过11次(假如数字都只出现1次,那么1就出现了11次);
所以后面次数的10个数字加起来>=20 && <=21,单个数字<=11;
最后得出未知的字符串为10个[1-11]的数字,这10个数字相加=20||=21。
/** * 找出这10个数字 * @param totalCount 剩下的总次数 * @param arr 10个数字的数组j * @param i 从第几个数字开始找 * @return * 查找方式:从第一个数字开始的最大次数开始找,找剩下数字的所有组合,如果找不到就-1; * 剩下数字的次数总数不超过21减去前面数字的总次数; * 同时注意每一位数字最大11; * * 11,10,0,0,0,0,0,0,0,0 第一轮第一个数字最大11,剩余次数(21-11=10)顺到下一位; * 11,9,1,0,0,0,0,0,0,0 第二轮第二个数字减1,剩余次数(21-11-9=1)顺到下一位(第三位); * 11,9,1,0,0,0,0,0,0,0 第二轮第二个数字减1,剩余次数(21-11-9=1)顺到下一位(第三位); * 11,9,0,1,0,0,0,0,0,0 第三轮第三个数字减1,剩余次数(21-11-9-0=1)顺到下一位(第四位),每个数字直到减到0,上一位才减1; * ... * 10,11,0,0,0,0,0,0,0,0 直接第二个数字减到0,第一位才减1,然后剩余次数(21-10=11)顺到下一位 * 10,10,1,0,0,0,0,0,0,0 * ... * 0,0,0,0,0,0,0,0,0,0 直到全部减到0则判断无解 */ public static boolean findCount(int totalCount, int[] arr, int i){ int count = totalCount > 11 ? 11 : totalCount; //每个数字最大不超过11次 if(i < arr.length){ do{ arr[i] = count; int remainCount = totalCount - arr[i]; if(remainCount == 0){ //如果没有剩余次数了就判断是否匹配 // System.out.println(join(arr)); if(checkNum(arr)){ return true; } }else{ //如果当前数字组合不结果不匹配则找该剩下组合 if(findCount(remainCount, arr, i + 1)){ return true; } } //当前数字找不到就找下一个数字 count--; }while(count >= 0 && i < arr.length - 1); //如果全部组合不匹配则归零,上一位数字减1重新匹配 arr[i] = 0; } return false; } /** * 测试数组的结果对不对 * @param arr * @return */ public static boolean checkNum(int[] arr){ String s = "0123456789" + join(arr).replace(",", ""); //将所有数字合并成一个字符串,统计出现次数 boolean isTrue = true; String ss = s.toString(); for (int i = 0; i < arr.length; i++) { //统计每个数字出现次数并判断是否符合结果 int count = ss.length() - ss.replaceAll(""+i, "").length(); if(arr[i] != count){ isTrue = false; break; } } return isTrue; } public static void main(String[] args) { int[] arr = new int[10]; //假如总次数为21次,从第1位开始查找 if(findCount(21, arr, 0)){ System.out.println("结果是:"); for (int i = 0; i < arr.length; i++) { System.out.println(i + "出现次数:" + arr[i]); } }else{ System.out.println("无解"); } arr = new int[10]; //假如总次数为20次,从第1位开始查找 if(findCount(20, arr, 0)){ System.out.println("结果是:"); for (int i = 0; i < arr.length; i++) { System.out.println(i + "出现次数:" + arr[i]); } }else{ System.out.println("无解"); } arr = new int[10]; //假如0出现次数为1次,总次数为20次,从第2位开始查找 arr[0] = 1; if(findCount(19, arr, 1)){ System.out.println("结果是:"); for (int i = 0; i < arr.length; i++) { System.out.println(i + "出现次数:" + arr[i]); } }else{ System.out.println("无解"); } } public static String join(final int[] array) { if (array == null) { return null; } char separator = ','; int startIndex = 0; int endIndex = array.length; final StringBuilder buf = new StringBuilder(endIndex * 16); for (int i = startIndex; i < endIndex; i++) { if (i > startIndex) { buf.append(separator); } buf.append(array[i]); } return buf.toString(); }
相关文章推荐
- java国际化时使用fmt标签
- ubuntu14.04 apt-get安装JDK
- Java设计模式之装饰者模式
- Java字节码指令简介
- java——认识队列和运算机制
- java读取word中的表格并存入到mysql数据库中实例
- Java实现栈
- Java类装载过程
- Excel导出工具类.
- 实用的但偏执的Java编程技术10个分享
- Java多线程 - 第一篇
- java多线程中的生产者和消费者队列
- Struts2的Action属性名和s三种实现方法
- SpringMVC接收前端提交的对象数组
- Java天地 学习探讨Java Spring中使用classpath加载配置文件浅析
- Java Label
- Spring4.x+Hibernate4.x整合出现的问题
- Spring boot实现数据库读写分离
- Java Comparable 和Comparator接口的使用及区别
- leetcode-Java-83. Remove Duplicates from Sorted List