- 论坛徽章:
- 0
|
原帖由 rubee 于 2007-8-14 22:10 发表 ![]()
第二题:某地刑侦大队对涉及六个嫌疑人的一桩疑案进行分析:
A、B 至少有一人作案;
A、E、F 三人中至少有两人参与作案;
A、D 不可能是同案犯;
B、C 或同时作案,或与本案无关;
C、D 中有且仅有一人作案;
如果 D 没有参与作案,则 E 也不可能参与作案。
试编一程序,将作案人找出来
比较笨,用的是穷举!!
跟上题一样,排列出所有可能的罪犯组合类型,
我们用一个int来表达,最低位为A,依次升高为B、C、D、E、F
(既A是第0位、B第1位、C2、D3、E4、F5)
如果A、B、D是罪犯的话,那表达出来就是
(1<<0)+(1<<1)+(1<<3) = 1+2+8 = 13
现在列举所有的罪犯组合,只需要循环,从0到(2^6-1)
思想是这个样子的,把所有一切都转化成数目的思考!
比如X、Y同犯,则表明数目是2
要判断罪犯列表中X、Y是否是同犯,
只要把X、Y的组合与整体的罪犯组合与运算后,
2进制中依然能数出来2个1,则确定X、Y是同犯成立
statu2int函数就是属状态码的2进制中数有多少个罪犯数目的
static int statu2int( int statu )
check则用要判断的罪犯列表、他们的关系数量,与输入的假设犯罪组合进行比较,如果成立返回1,否则返回0
static int check( int men, int num, int condition )
main中,循环所有组合,依次判断题目中的条件,
如果不符合,就continue;如果都符合,则打印出当前罪犯组合
下面看具体代码
- #include <stdio.h>
- #include <math.h>
- #define NUM 6
- int statu = 0;
- enum man { A=0, B, C, D, E, F };
- static int statu2int( int statu )
- {
- int i, retval = 0;
- for( i=0; i<NUM; i++ )
- if( (statu>>i)&0x01 ) retval++;
- return (retval);
- };
- static int check( int men, int num, int condition )
- {
- if( num==statu2int(men&condition) )
- return 1;
- else
- return 0;
- };
- int main( void )
- {
- int guess, i;
- for( guess=0; guess<pow(2,NUM); guess++ )
- {
- /*A和B至少有1个人作案*/
- if( !( check( (1<<A)+(1<<B), 1, guess ) || check( (1<<A)+(1<<B), 2, guess ) ) ) continue;
- /*A、E、F至少有2个人作案*/
- if( !( check( (1<<A)+(1<<E)+(1<<F), 2, guess ) || check( (1<<A)+(1<<E)+(1<<F), 3, guess ) ) ) continue;
- /*A、D不可能是同犯*/
- if( check( (1<<A)+(1<<D), 2, guess ) ) continue;
- /*B、C或同时作案,或与本案无关*/
- if( !( check( (1<<B)+(1<<C), 0, guess ) || check( (1<<B)+(1<<C), 2, guess ) ) ) continue;
- /*C、D 中有且仅有一人作案*/
- if( !check( (1<<C)+(1<<D), 1, guess ) ) continue;
- /*如果 D 没有参与作案,则 E 也不可能参与作案*/
- if( check( (1<<D), 0, guess ) )
- if( !check( (1<<E), 0, guess ) ) continue;
- for( i=0; i<NUM; i++ )
- {
- if( (guess>>i)&0x01 ) fputc( 'A'+i, stdout );
- }
- printf( "\n" );
- }
- return 0;
- }
复制代码
编译运行
dorainm@lfs ~/workroom/c/conseq $ gcc -o conseq2 conseq2.c
dorainm@lfs ~/workroom/c/conseq $ ./conseq2
ABCF
dorainm@lfs ~/workroom/c/conseq $
犯罪列表出来了:)
[ 本帖最后由 dorainm 于 2007-9-3 05:28 编辑 ] |
|