您的位置:首页 > 编程语言 > Java开发

请用数字填空,使正面十句话都正确,用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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: