Java语言高职组最后一题题

A、B、C、D、E、F、G、H、I、J 共10名学生有可能参加本次计算机竞赛,也可能不参加。因为某种原因,他们是否参赛受到下列条件的约束:
A、B、C、D、E、F、G、H、I、J 共10名学生有可能参加本次计算机竞赛,也可能不参加。因为某种原因,他们是否参赛受到下列条件的约束:
   1. 如果A参加,B也参加;
   2. 如果C不参加,D也不参加;
   3. A和C中只能有一个人参加;
   4. B和D中有且仅有一个人参加;
   5. D、E、F、G、H 中至少有2人参加;
   6. C和G或者都参加,或者都不参加;
   7. C、E、G、I中至多只能2人参加   
   8. 如果E参加,那么F和G也都参加。
   9. 如果F参加,G、H就不能参加
   10. 如果I、J都不参加,H必须参加
请编程根据这些条件判断这10名同学中参赛者名单。如果有多种可能,则输出所有的可能情况。每种情况占一行。参赛同学按字母升序排列,用空格分隔。



答案

就是一种可能的情况。
public class CS {

    private static long data 0x3FF;

    public static void main(String[] args) {
        
        boolean state true;
        
        for(;data>=0;data--){
            
            state true;
            
            // 如果A参加,B也参加;
            state (getState('A') && getState('B') || !getState('A')  state false;
            
            // 如果C不参加,D也不参加;
            state !getState('C') && !getState('D')  || getState('C')  state false;
            
            // A和C中只能有一个人参加
            state getState('A') != getState('C') || (!getState('A') && getState('C'))  state false;
            
            // B和D中有且仅有一个人参加
            state getState('B') != getState('D')  state false;
            
            // D、E、F、G、H 中至少有2人参加;
            Boolean [] defgh {getState('D'),getState('E'),getState('F'),getState('G'),getState('H')};
            int num 0;
            for(boolean defgh){
                if(b){
                    num++;
                }
            }
            state num>=2 state false;
            
            // C和G或者都参加,或者都不参加;
            state getState('C') == getState('G')  state false;
            
            // C、E、G、I中至多只能2人参加
            Boolean [] ceghi {getState('C'),getState('E'),getState('G'),getState('I')};
            num 0;
            for(boolean ceghi){
                if(b){
                    num++;
                }
            }
            state num==2 state false;
            
            // 如果E参加,那么F和G也都参加。
            state (getState('E') && getState('F') && getState('G') ||  !getState('E') state false;
            
            // 如果F参加,G、H就不能参加
            state (getState('F') && !getState('G') && !getState('H') ||  !getState('F') state false;
            
            // 如果I、J都不参加,H必须参加
            state (!getState('I') && !getState('J') && getState('H') ||  getState('I')  || getState('J') state false;
            
            if(state){
                print();
            }
        }
    }
    
    //data 的从低位到高位分别表不A-J,1表示参加,0表示不参加
    private static boolean getState(char c){
        int c-'A';
        long 1<< p;
        return (data != 0;
    }
    
    //输出可行的方案
    private static void print(){        
        char[] chars {'A','B','C','D','E','F','G','H','I','J'};
        for(int =0;i
            if(getState(chars[i])){
                System.out.print(" "+chars[i]);
            }
        }
        System.out.println();
    }
    

}

首先要知道这是一种2进制思路,A-J的参加或不参加分别用1,0表示,
那么,如果都参加,就相当于1111111111,如果都不参加就相当于0000000000
好了这就是最大状态和最小状态,也就是符合题意的状态在0000000000到1111111111之间
11111111111的二进制也就是16进制的3FF,00000000000也就是10进制的0
所以程序中使用了long data 0x3FF; 
然后循环,每次data-1,直到data==0结束,也就是在0000000000到1111111111之间查找,分别通过各种约束条件过滤数据,这就是主程序的部分

再来看getState(char c)
1111111111假设分别对应JIHGFEDCBA的参赛状态,那么A的状态就是最右边的1,B的右数第二个,C是右数第三个,等等,这样通过移位来找到每个字母对应的状态,对于参数传进来的c,通过计算c-'A',可以得到该字母的右数的位置,比如'A'-'A'=0,'B'-'A'=1,'C'-'A'=2等等,用来确定右数的位置,然后把1右移右数的个数,比如1<<0得到1,1<<1得到10,1<<2得到100等等,再用来跟data进行&运算,得到某队员的状态,比如对于处于某个状态的data,假设为1110000010,我们来查看'C'的状态,'C'-'A'=2,1<<2=100,然后进行&运算1110000010 0000000100(这里注意二进制的位置补齐,高位自动补0),得到结果为0000000000,即结果为0,所以'C'的状态是没参赛,再看'B','B'-'A'=1,1<<1=10,然后进行&运算
1110000010 0000000010,得到结果为0000000010,即不是0,所以'B'的状态为参赛

明白了这些,那些至少2人,只能2人的就是判断data的2进制的相应位置的1的个数,这里就不用再解释了

原文地址:https://www.cnblogs.com/liuzhuqing/p/7480671.html