zoukankan      html  css  js  c++  java
  • 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的个数,这里就不用再解释了

  • 相关阅读:
    UVA 1025 A Spy in the Metro DP水题
    ZOJ 3814 Sawtooth Puzzle BFS
    ZOJ 3816 Generalized Palindromic Number
    UVA 10859 Placing Lampposts 树形DP
    UVA 11825 Hackers' Crackdown 状压DP
    POJ 2887 Big String 线段树 离线处理
    POJ 1635 Subway tree systems Hash法判断有根树是否同构
    BZOJ 3110 k大数查询 & 树套树
    sdoi 2009 & 状态压缩
    来自于2016.2.24的flag
  • 原文地址:https://www.cnblogs.com/liuzhuqing/p/7480671.html
Copyright © 2011-2022 走看看