- 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<o.length;x++)
- for(int y = 0;y<o[x].length;y++)
- b[x][y] = o[x][y];
- return b;
-
- }
- }
复制代码 |