猜数字是一个比较经典的游戏。有若干的空,每个空可以填入若干种数字,每次填入数字后,提示有几个数字是正确的,有几个数字位置填写对了。如果位置正确的数字和填入数字个数相等则得到正确答案。

这里只针对一种简单的情况(有3个空,每个空可以填入0-3中的一个数字)使用穷举法求解。想了解更多可以看论文https://arxiv.org/pdf/1305.1010.pdf

3个空,每个空填入0-3的数字,则所有的情况有4*4*4=64种可能。随便猜一个数,返回结果可以表示成(0,0)(1,0)(1,1)(2,0)(2,1)(2,2)(3,0)(3,1)(3,2)(3,3)(4,0)(4,1)(4,2)(4,3)(4,4)中的一种,(1,0)表示有1个颜色正确0个位置正确。随便猜一个数字就可以把64中可能分配到不同的结果集中,如果某个结果集中只有一种可能,表示这次猜测能得到该结果,如果结果集中有多种可能则继续猜测。
随便猜测时把64种可能都试一遍,找到平均猜测次数最小的就是我们想要的答案了。代码如下:

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
//存放当前的状态
class Point{final int N = 3;//该类只能操作3位数的猜数字游戏   int[] colors = new int[N];  Point(){}Point(int i,int j,int k){this.colors[0] = i;this.colors[1] = j;this.colors[2] = k;}//获取正确数字个数public int rightNumber(Point p){int num = 0;boolean a[] = new boolean[N];for(int i=0;i<N;i++){a[i] = false;}for(int i=0;i<N;i++){for(int j=0;j<N;j++){if(!a[j]){if(this.colors[i]== p.colors[j]){num++;a[j]=  true;break;}}}}return num;}//位置和颜色都正确的个数public int rightStatus(Point p){int num = 0;for(int i=0;i<N;i++){if(this.colors[i] == p.colors[i]){num++;}}return num;}
}
//查找最优方法
public class GetBestWay {   /*** 根据猜测进行分组* @param possble  所有的可能* @param rule  如果用户输入的是rule,把所有可能进行分组 * @return   所有分组的情况*/public static List<ArrayList<Point> > getPossibleArray(List<Point> possble,Point rule){List<ArrayList<Point> > eligible = new ArrayList<ArrayList<Point> >();//因为只有3个数字,颜色正确个数有4种可能,//颜色和位置都正确右4种可能,组合起来有16种可能for(int i=0;i<16;i++){ArrayList<Point> temp = new ArrayList<Point>();eligible.add(temp);}for(int i=0;i<possble.size();i++){int r1 = possble.get(i).rightNumber(rule);int r2 = possble.get(i).rightStatus(rule);//把所有可能分配到不同的集合中eligible.get(r1*4+r2).add(possble.get(i));}return eligible;}/*** 已知用户输入和正确数字个数与正确位置个数,求所有可能* @param possble  输入所有的可能* @param rule   用户输入* @param result   result[0]表示正确数字个数,result[1]表示位置正确个数* @return  根据正确数字个数和正确位置个数,有哪些可能能满足*/public static List<Point> getPossible(List<Point> possble,Point rule,int[] result){List<Point> eligible = new ArrayList<Point>();if(possble.size()==1){return eligible;}for(int i=0;i<possble.size();i++){int r1 = possble.get(i).rightNumber(rule);int r2 = possble.get(i).rightStatus(rule);//与result相符,添加到结果集中if(r1 == result[0] && r2 == result[1]){eligible.add(possble.get(i));}}return eligible;}//打印所有可能性public static void print(List<Point> possble){for(int i=0;i<possble.size();i++){for(int j=0;j<possble.get(i).colors.length;j++){System.out.print(possble.get(i).colors[j]);System.out.print(" ");}System.out.print("; ");}System.out.println();}/*** 寻找最优解* @param possible 所有的可能* @param bestPoint 返回最优选择* @return  最优选择平均查找次数*/public static double findBestPoint(List<Point> possible,Point bestPoint){int n = possible.size();if(n==0)return 0;if(n==1){bestPoint.colors = possible.get(0).colors;return 1;}double min = 999999;//因为穷举法速度太慢,这里使用了贪心策略。因为该贪心方法最后求得的结果也是206/64,是可以的for(int i=0;i<n;i++){double result = 1;Point rule = possible.get(i);List<ArrayList<Point> > possibleList = getPossibleArray(possible,rule);//第16种是正确个数和位置都为3,也就是得到正确结果,不用继续查找for(int j=0;j<15;j++){List<Point> temp = possibleList.get(j);if(temp.size()!=0){result+=temp.size()/(double)n*findBestPoint(temp,new Point());}}if(min>result){min = result;bestPoint.colors = rule.colors;}}return min;}public static void main(String[] args) {Scanner cin = new Scanner(System.in);List<Point> possible = new ArrayList<Point>();//初始化,有三个数字要猜。每个数字是0-3中的一种for(int i=0;i<4;i++){for(int j=0;j<4;j++){for(int k=0;k<4;k++){Point t = new Point(i,j,k);possible.add(t);}}}       Point bestPoint = new Point();int[] rightNum = new int[2];while(possible.size()>0){if(possible.size()==1){System.out.println("当前只有一个选择");print(possible);break;}System.out.println("当前集合中包含所有可能为:");print(possible);//根据当前情况查找最优解double result = findBestPoint(possible,bestPoint);System.out.println("还需要的平均步数为:"+result);System.out.println("推荐最优选择为:"+ bestPoint.colors[0]+" "+bestPoint.colors[1]+" "+bestPoint.colors[2]);System.out.println("你的选择是:");bestPoint.colors[0] = cin.nextInt();bestPoint.colors[1] = cin.nextInt();bestPoint.colors[2] = cin.nextInt();System.out.println("输出结果是:");rightNum[0] = cin.nextInt();rightNum[1] = cin.nextInt();possible = getPossible(possible, bestPoint, rightNum);}System.out.println("结束");}
}

猜数字游戏穷举法(迅雷水晶矿场中的游戏求解)相关推荐

  1. 常用算法总结(穷举法、贪心算法、递归与分治算法、回溯算法、数值概率算法)

    博主联系方式: QQ:1540984562 微信:wxid_nz49532kbh9u22 QQ交流群:892023501 目录 1.穷举法 2.贪心算法 3.递归与分治算法 4.回溯算法 5.数值概率 ...

  2. 百鸡问题用计算机什么法解决,《穷举法解决问题》教学设计

    一.教学目标 1.知识与技能 ⑴了解穷举法的基本概念及用穷举法设计算法的基本过程. ⑵分析建立正确的数学模型,归纳穷举法穷举技巧. ⑶能够根据具体问题的要求,使用穷举法设计算法,编写程序求解问题. 2 ...

  3. 常见算法思想——穷举法

    常见算法思想--穷举算法 简单介绍 详细介绍 算法思路 算法特点 算法优化 实例演示 题目描述 题目分析 完整代码 简单介绍   在进行归纳推理时,如果逐个考察了某类事件的所有可能情况,因而得出一般结 ...

  4. 常用算法回顾——穷举法

    文章目录 一.穷举法 定义 算法思路 算法优缺点 示例: 一.穷举法 定义 穷举法是算法设计中经常使用的一种方法,基本思想是问题的要求将问题的所有可能的输入一一进行验证,看是否满足问题的条件,从而找到 ...

  5. JS if 水仙花数 游乐园门票计算 闰年 三元运算符 for循环 算法 穷举法 While 拔萝卜 等差数 随机数函数random 区间数 猜数字

         算法题 水仙花数  数学方法 字符串方法   游乐园门票计算  Switch   闰年 <body> <script>var month = Number(promp ...

  6. python算24点穷举法_24点游戏7节课–第1节-游戏介绍与基本算法 | 学步园

    这仅仅是一个控制台(DOS窗口下)的小游戏--有人欢喜有人烦了.欢喜的是因为可以专心于游戏逻辑自身过程,就算你只学过C++简单的屏幕输入输出(cin.cout ),乃至换用java,C#也可以写这个小 ...

  7. 关于Java穷举法对24点卡牌游戏规定时间内输入判断对错的程序

    24点游戏是经典的纸牌益智游戏. 常见游戏规则: 从扑克中每次取出4张牌.使用加减乘除,第一个能得出24者为赢.(其中,J代表11,Q代表12,K代表13,A代表1),按照要求编程解决24点游戏. 随 ...

  8. 穷举法java_OpenJudge 4146:数字方格 java穷举法

    首先是题目描述: 描述 如上图,有3个方格,每个方格里面都有一个整数a1,a2,a3.已知0<=a1,a2,a3<=n,而且a1+a2是2的倍数,a2+a3是3的倍数,a1+a2+a3是5 ...

  9. 服务器被穷举法暴力爆破、攻击的简单应对方案。

    年前的时候为了看某站的视频,用自己的服务器搭了一把梯子.平常就是扶墙用,没怎么维护过. 结果最近看了一下用户登录记录,有10万个斯巴达勇士正在冲我们家水晶...这里简单记录一下服务器被人攻击的应对方案 ...

最新文章

  1. 课程 | 想成为高薪、抢手又能改变世界的机器学习工程师?
  2. StructureMap 代码分析之Widget 之Registry 分析 (1)
  3. python话雷达图-python使用matplotlib绘制雷达图
  4. MySQL学习笔记_9_MySQL高级操作(上)
  5. window10 java 设置环境变量
  6. 【MySQL】 如何在“海啸”下保命
  7. 所有的面试问题都可以归结为这三类(附回答套路)
  8. abaqus帮助文档html,2534-VUMAT用户子程序翻译ABAQUS帮助手册.doc
  9. xlsxwriter设置Excel的表格边框
  10. oj刷题 Problem J: 软件工程
  11. Unity-瓦片地图详解
  12. egret给对象涂颜色
  13. puppet单机模型
  14. 量化框架backtrader之一文读懂Indicator指标
  15. 无穷小微积分词汇索引怎么使用?
  16. 外存及虚拟存储器管理
  17. springboot异步和切面_Spring异步编程 | 你的@Async就真的异步吗 ☞ 异步历险奇遇记...
  18. 看完涨薪2K+_____2019 JAVA 必刷面试题
  19. java游戏西游孙悟空_玩了这本《西游冒险手册》,我才真正理解了孙悟空
  20. Charles抓包 - 手机

热门文章

  1. 深圳车公庙的由来(转自深圳原住民网)
  2. mysql 存储位图_24位位图存放格式说明
  3. 证书cer转换.key和.pem文件
  4. 基于MATLAB的数字PID直流电机调速系统
  5. android手机收不到彩信,小米4手机收不到彩信是什么原因?小米4彩信设置教程
  6. 思维导图从入门到大神
  7. java泛解析_域名解析和域名泛解析
  8. yanshee机器人代码
  9. 电路交换与分组交换的区别?优劣对比
  10. ExternalInterface的简单使用方法