求不同的解法

lin12345 2008-12-07 06:55:13
2. A、B、C、D、E五名学生有可能参加计算机竞赛,根据下列条件判断哪些
人参加了竞赛:

(1)A参加时,B也参加;

(2)B和C只有一个人参加;

(3)C和D或者都参加,或者都不参加;

(4)D和E中至少有一个人参加;

(5)如果E参加,那么A和D也都参加。



//利用二进制来进行判断


#include<iostream>
#include<math.h>

using namespace std;

const int num=5; //有几个人

//计算 2的连续 n 次方的和
int sum(int n) {
int s=0;

for(int i=0;i<n;++i)
s+=pow(2,i);

return s;
}



//将十进制变为二进制
void de_to_bi(int s,int *array) {
for(int i=num-1;i>=0;--i) {
array[i]=s%2;
s/=2;
}
}


//五人的顺序对应 A,B,C,D,E
bool isMatch(int *arr) {
bool res=true;

//A go,B not go
if( arr[0]==1&&arr[1]==0 ) res=false;

//b and c both not go
if( arr[1]==1&&arr[2]==1 ) res=false;

//c go and d not d go,or c not go and d go
if( (arr[2]==1&&arr[3]==0)||(arr[2]==0&&arr[3]==1) )
res=false;

// d and e not go
if( arr[3]==0&&arr[4]==0 )
res=false;

// e go and a or d not go
if( arr[4]==1&&(arr[0]==0||arr[3]==0) )
res=false;

return res;
}



//输出结果
void print(int *arr) {
for(int i=0;i<num;++i) {
if( arr[i]==1 )
cout<<(char)(i+'A')<<" go"<<endl;
else
cout<<(char)(i+'A')<<" not go"<<endl;
}
}



int main() {
int s=sum(num);

int binary[num]; //存放对应的二进制的数组

for(int i=0;i<num;++i)
binary[i]=0;

for(int j=0;j<s;++j) {
de_to_bi(j,binary);

if( isMatch(binary) )
print(binary);
}

system("pause");
return 0;
}
这是我的解法,用二进制来做,各位对这有什么改进或有更好的解法,请提出来,分不够再加

这程序能正常运行,并输出结果.
结果是C和D去
...全文
114 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
fiyaa 2008-12-08
  • 打赏
  • 举报
回复
新手,学习...
Love AI 2008-12-08
  • 打赏
  • 举报
回复
没有,是一个求解命题可满足问题的工具

http://eao.sysu.edu.cn/home2/huiyzhongj.asp?id=15
lin12345 2008-12-07
  • 打赏
  • 举报
回复
SAT求解器是什么,C++有这东西吗
Love AI 2008-12-07
  • 打赏
  • 举报
回复
所有类似的问题都可以调用SAT求解器直接进行求解:
步骤:
编码为CNF公式:
(1) A参加时,B也参加了:
A->B 也即 not A or B
(2) B和C只有一个人参加:
B or C
not B or not C
(3) C和D或者都参加了,或者都没参加:
C or not D
not C or not D
(4) D和E至少有一个人参加了:
D or E
(5) 如果E参加,那么A和D也都参加:
E -> ( A and D ) 也即
not E or A
not E or D
将所有公式合取称为KB
需要判断A是否参加了,只需调用SAT求解器判断
KB and A是否可满足
toadzw 2008-12-07
  • 打赏
  • 举报
回复
#include <iostream>
using namespace std;
void main()
{
int a,b,c,d,e;
for(a=0;a<2;a++)
for(b=0;b<2;b++)
for(c=0;c<2;c++)
for(d=0;d<2;d++)
for(e=0;e<2;e++)
{
if ((a==1&&b==1)||(a==0))
if((b==1&&c==0)||(b==0&&c==1))
if(c==d)
if(d==1||e==1)
if((e==1&&a==1&&d==1)||e==0)
{
cout<<"参加的是:"<<endl;
if(a)
cout<<"a"<<endl;
if(b)
cout<<"b"<<endl;
if(c)
cout<<"c"<<endl;
if(d)
cout<<"d"<<endl;
if(e)
cout<<"e"<<endl;
}

}
}


t1397018 2008-12-07
  • 打赏
  • 举报
回复
我第一个也想到了楼主的方法
所以呢只好换一种了,这个方法比较变态,我称之为
暴力破解法~~!

#include <iostream>
using namespace std;
void main()
{
int a,b,c,d,e;
for(a=0;a<2;a++)
for(b=0;b<2;b++)
for(c=0;c<2;c++)
for(d=0;d<2;d++)
for(e=0;e<2;e++)
{
if ((a==1&&b==1)||(a==0))
if((b==1&&c==0)||(b==0&&c==1))
if(c==d)
if(d==1||e==1)
if((e==1&&a==1&&d==1)||e==0)
{
cout<<"参加的是:"<<endl;
if(a)
cout<<"a"<<endl;
if(b)
cout<<"b"<<endl;
if(c)
cout<<"c"<<endl;
if(d)
cout<<"d"<<endl;
if(e)
cout<<"e"<<endl;
}

}
}


结果
CD
成功哦耶~~
zapdos 2008-12-07
  • 打赏
  • 举报
回复
列个真值表不就OK了

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧