java逻辑编程题_用Java编程解决一道逻辑推理题

package mytest;

import java.util.Scanner;

public class Test14 {

/**

* 竞赛结果表明,他们都说对了一半,说错了一半,并且无并列名次,试编程输出a,b,c,d的各个名次。

* 分析:

* 我们将老师的预测列成二维数组形式。行数是老师的人数,也就是3.列数为5。

* 第一列表示该老师预测对的个数。由于一个老师预测了两部分,所以将初始值都设置为2.

* 我们首先假设第一个老师的第一部分预测时对的,那么就需要将预测了同一人,预测了同一名次,

* 以及第一个老师的另一部分预测全部设置为null,并且将相应的预测数减1.直到某一个预测数为0时,

* 那么这个假设就是错误的。

* @param args

*/

public static void main(String[] args) {

String[][] str = new String[3][5];

for(int x = 0;x<3;x++){

str[x][0] = 2+"";

}

System.out.println("注意:输入时人与名次用等号连接,人与人之间用逗号隔开。");

for(int x = 1;x<=3;x++){

System.out.print("请输入第"+x+"个老师的预测:");

Scanner sc = new Scanner(System.in);

String a = sc.next();

int firstd = a.indexOf("=");

int lastd = a.lastIndexOf("=");

int dou = a.indexOf(",");

str[x-1][Integer.parseInt(a.substring(firstd+1,dou))] = a.substring(0, firstd);

str[x-1][Integer.parseInt(a.substring(lastd+1))] = a.substring(dou+1, lastd);

}

String[][] bei = new String[3][5];//将数组备份,方便还原。

bei= fu(str,bei);

//由于第一个老师肯定会预测对一个,所以不需要进行行的遍历。

for(int y = 1;y<5;y++){

if(str[0][y] == null)

continue;

//假设第一个老师的当前预测是正确的,那么需要进行判断。

boolean b = hanshu(0,y,str);

//如果b是真的,那么就需要将所有的地方都进行一次判断。

//因为还有可能存在别的相矛盾的预测。

if(b){

k:for(int m = 1;m<3;m++){//第一个老师的正确预测已经假设过了,所以不需要从0开始。

for(int n = 1;n<5;n++)

if(str[m][n]!=null){

b = b&&hanshu(m,n,str);

if(!b)//如果某个预测出现了错误,那么就直接跳出循环即可。

break k;//跳出最外层,因为这个假设不对。

}

}

}

if(b){//如果当前假设成立,那么遍历输出相应的结果。

for(int x1 = 0;x1<3;x1++){

for(int y1 = 1;y1<5;y1++){

if(str[x1][y1]!=null)

System.out.println(str[x1][y1]+"是第"+y1+"名");

}

}

}

else{

if(y == 4){//当第一个老师的所有预测都是错误的时候,题目就无法完成了。

System.out.println("无法推断出名次。");

break;

}

str = fu(bei,str);//通过上面的操作,已经将str进行了改变,所以需要还原。

}

}

}

//改变同行、同列以及相同的人后,判断是不是出现错误。

private static boolean hanshu(int col, int row, String[][] str) {

boolean b= false;

for(int x = 0;x<3;x++){

for(int y = 1;y<5;y++){

b= false;//每一个位置开始时假设没有发生变化。

if(str[x][y]!=null){

if(x == col&&y!=row){//同行不同列

str[x][y] = null;

b = true;

}

else if( y == row&&x!=col){//同列不同行

str[x][y] = null;

b = true;

}

else if(str[x][y].equals(str[col][row])&&x!=col&&y!=row){//即不同列也不同行,但是预测的人是一样的。

str[x][y] = null;

b = true;

}

if(b){//如果该位置发生了变化,那么就将它所在的行的预测数减1.

str[x][0] = Integer.parseInt(str[x][0])-1+"";

if(str[x][0].equals("0"))

return false;

}

}

}

}

return true;

}

//将String[][]还原。

private static String[][] fu(String[][] o,String[][] b){

for(int x = 0;x

for(int y = 0;y

b[x][y] = o[x][y];

return b;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值