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 b : 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 b : 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 p = c-'A';
long b = 1<< p;
return (data & b ) != 0;
}
//输出可行的方案
private static void print(){
char[] chars = {'A','B','C','D','E','F','G','H','I','J'};
for(int i =0;i<chars.length;i++){
if(getState(chars[i])){
System.out.print(" "+chars[i]);
}
}
System.out.println();
}
}
//
这道题实在看不懂,还望高手一一指点,还有关于位移的运算一般都用在什么地方,到底怎么办,如果方便的话请加QQ细细说明,做个朋友,1215811695
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 b : 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 b : 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 p = c-'A';
long b = 1<< p;
return (data & b ) != 0;
}
//输出可行的方案
private static void print(){
char[] chars = {'A','B','C','D','E','F','G','H','I','J'};
for(int i =0;i<chars.length;i++){
if(getState(chars[i])){
System.out.print(" "+chars[i]);
}
}
System.out.println();
}
}
//
这道题实在看不懂,还望高手一一指点,还有关于位移的运算一般都用在什么地方,到底怎么办,如果方便的话请加QQ细细说明,做个朋友,1215811695
解决方案 »
- 关于java位操作的问题
- Hashtable被HashMap所取代
- jdk问题
- java 加载类占用内存的问题?
- 怎样使得jtable在编辑状态的时候,显示多行?
- to 大侠,如何在JAVA中设置系统时钟,精确到毫秒级?
- 一个从C++转学JAVA的初学者的问题,请各位有时间看看,都是一些入门的问题,不过很钻牛角尖,可能我理解的不深?
- 怎么编译不了
- 怎样把一个对象拷贝到另一个对象?
- 新手请教:哪位帮忙看看这段程序(用Applet画折线图)参数是接收到了并付给了数组,可就是出不了图???
- number1和number2的值都为10000000000,求sum程序表示错误。
- jdk1.7中如何使用BASE64Encoder加密?
主循环每次递减就是不断遍历各种情况getState中 p表示传入函数中的是第几个人
b = 1 << p 表示将1左移p位, 比如 传入'C', p = 2, b = 100, data & b的结果为 (以0x3ff为例)100 != 0
也就是说 C参加比赛 没问题了吧?
那么,如果都参加,就相当于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的个数,这里就不用再解释了
1. 由条件8,9可以推断出,如果E参加,那么F,G也参加,如果F参加G,H就不能参加可以得出,E是不会参加的。
2. 然后我们分情况考虑
a. A参加,则ABCDE=11000(这个根据前4条推断出),好,然后再考虑FGHIJ的参加情况,由于条件6,则G是0(不参加),由条件5,所以F和H必须参加,但这个又和条件9相悖,所以可以断定,A是不参加的。
b. 由上面的推断结果,A=0,E=0,还是由前4条和第6条,推断出ABCDEG结果有3种情况(000100,010000,011001),说明一下,大家可能对条件3理解不同,如果理解成A和C必须且只能有1个参加的话,那可以肯定ABCDE=011001,且后面的结果直接可以推断出来(应该是这样的,我估计),但是我猜测出题者的意图和条件4的比较,我认为条件3的意思是A和C最多只有1个人参加。
好,我们再来分开讨论
1>. ABCDEG=010000,根据条件5,则F,H必须参加,但这又和条件9相悖,PASS
2>. ABCDEG=000100,考虑FHIJ的情况了
3>. ABCDEG=011001,根据条件9和5,得出F=0,H=1,根据条件7,得出I=0,最后只需要考虑J的情况了至于上面的分析,已经是我得出的最小化了,代码就不写了,思路出来了,就简单了。
1. 由条件8,9可以推断出,如果E参加,那么F,G也参加,如果F参加G,H就不能参加可以得出,E是不会参加的。
2. 然后我们分情况考虑
a. A参加,则ABCDE=11000(这个根据前4条推断出),好,然后再考虑FGHIJ的参加情况,由于条件6,则G是0(不参
///
回复15楼,你的分析我怎么有点看不懂,11000代表什么,像这种分析是不是数学上的,如果数学 基础不好,怎么办,,,
二、C D G H
三、C D G H J
四、B C G H
五、B C G H J