大众比萨
来源:互联网 发布:2016网络出租屋新政策 编辑:程序博客网 时间:2024/06/10 05:13
你准备为你和朋友订一个比萨,他们告诉你每个人希望比萨里有什么和没有什么材料。当然,他们也明白只有一个比萨,所以没有人期望他所以的要求都得到满足。你订一个比萨满足他们每个人至少一项的要求吗?
比萨店提供的比萨口味如下,你可以在一个比萨中要或者不要当中的任何一项:
代码
口味
A
凤尾鱼
B
黑橄榄
C
加拿大熏肉
D
方丁大蒜
E
浓奶酪
F
鲜花椰菜
G
青辣椒
H
火腿
I
意大利香肠
J
加拉佩诺胡椒
K
波兰熏肠
L
瘦牛肉
M
蘑菇
N
脱脂羊乳酪
O
洋葱
P
胡椒
你的朋友给你一行文字描述他们的比萨口味。例如:
+O-H+P;
意味这某位朋友将接受一个包含洋葱,或不包含火腿,或带有胡椒的比萨。而
-E-I-D+A+J;
表示某位朋友将接受一个不包含浓奶酪或意大利香肠或方丁大蒜的,或带有凤尾鱼或加拉佩诺胡椒的比萨。
输入格式:
每个要求一行,并以分号结束。直到“.”表示所有约束都已输入结束。
输出格式:
如果存在可分配的方案则先输出一个长度为10 的字符串“Toppings: ”,紧接输出分配方案(按字母顺序由小到大)。
如果不存在可分配的方案则输出:“No pizza can satisfy these requests.”
输入输出样例:
Simple input 1
Output for the input
+A+B+C+D-E-F-G-H;
-A-B+C+D-E-F+G+H;
-A+B-C+D-E+F-G+H;
.
Toppings:
Simple input 2
Output for the input
+A+B+C+D;
+E+F+F+H;
+A+B-G;
+O+J-F;
+H+I+C;
+P;
+O+M+L;
+M-L+P;
.
Toppings: CELP
Simple input 3
Output for the input
+A;
-A;
.
No pizza can satisfy these requests.
解:
本题有两种解法:第一种比较复杂:首先将每个人的口味约束表示乘析取式,如+A -B+C表示成(A | !b | C),接着将所有人的口味表示成合取式,如+A+B和+C -D表示成( A | B ) & (C | !D),在将合取式中所有的括号展开变成析取式,这时使任意析取式为真的表达式都是问题的解,如(A & B)| (C &!D) 表示当A、B同时取真,或者C取真D取假时都是问题的解。
第二种方法是使用搜索算法,穷举所有的可能性,直到找到解为止。
尽管这种方法没有第一种那么聪明,但是由于实现起来比第一种简单的多,所以在这里采用搜索算法更科学些。
使用搜索算法时还要注意的两个问题是:1、比萨约束的存储方式;2、如何判断比萨是否符合要求。
这里使用位运算来表示比萨的约束方式:定义一个整形数组want[ PERSONMAX],其中PERSONMAX表示朋友的个数,want[ i ]表示第i 为朋友想要的口味,例如:
want[ i ]=00000000000000000000000001000011 表示第i个朋友想要口味凤尾鱼、黑橄榄和青辣椒。注意由于整形有32位而pizza的口味只有16种,所以这里高16为无效。
同理,定义另一个整形数组hate[PERSONMAX],hate[i]表示第i位朋友不想要的口味,例如:
hate[ i ]=00000000000000000000000000001100 表示第i个朋友不想要的口味有:方丁大蒜和加拿大熏肉。
于是在表述pizza是否符合某人的口味是只要进行如下判断:
(pizza & want[ i ] >0) ||(!pizza & hate[ i ] >0)
这种表示方法充分利用了位运算的优点,使得程序的处理十分的方便,而且节省了空间.
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<fcntl.h>
#include<io.h>
#define TYPELEN 16 //比萨口味的种类数
#define PERSONMAX 30 //最多的朋友人数
int pizza,want[PERSONMAX],hate[PERSONMAX],person;
char buf[TYPELEN*2];
void
setup(){
int count,i;
count=strlen(buf)-1; //最后一个是分号,因舍去。
memset(want+person,0,TYPELEN);
memset(hate+person,0,TYPELEN);
for(i=1;i<count;i+=2)
if(buf[i-1]=='+')
want[person]=want[person]|(1<<(buf[i]-65));
else
hate[person]=hate[person]|(1<<(buf[i]-65));
++person;
}
bool
checkPizza(){
bool flag;
int i;
for(pizza=0;pizza<65536;pizza++){ //搜索所有的可能pizza取值,直到成功
flag=true;
for(i=0;i<person;i++)
if(!((pizza&want[i])>0 || (!pizza&hate[i])>0)){
flag=false;
break;
}
if(flag) return true;
}
return false;
}
void
output(){
int i;
printf("Toppings: ");
for(i=0;i<TYPELEN;i++)
if(pizza&(1<<i)) putchar(i+65);
puts("/0");
}
#include<string.h>
#include<stdlib.h>
#include<fcntl.h>
#include<io.h>
#define TYPELEN 16 //比萨口味的种类数
#define PERSONMAX 30 //最多的朋友人数
int pizza,want[PERSONMAX],hate[PERSONMAX],person;
char buf[TYPELEN*2];
void
setup(){
int count,i;
count=strlen(buf)-1; //最后一个是分号,因舍去。
memset(want+person,0,TYPELEN);
memset(hate+person,0,TYPELEN);
for(i=1;i<count;i+=2)
if(buf[i-1]=='+')
want[person]=want[person]|(1<<(buf[i]-65));
else
hate[person]=hate[person]|(1<<(buf[i]-65));
++person;
}
bool
checkPizza(){
bool flag;
int i;
for(pizza=0;pizza<65536;pizza++){ //搜索所有的可能pizza取值,直到成功
flag=true;
for(i=0;i<person;i++)
if(!((pizza&want[i])>0 || (!pizza&hate[i])>0)){
flag=false;
break;
}
if(flag) return true;
}
return false;
}
void
output(){
int i;
printf("Toppings: ");
for(i=0;i<TYPELEN;i++)
if(pizza&(1<<i)) putchar(i+65);
puts("/0");
}
void
main(){
person=0;
while(1){
scanf("%s",buf);
if(buf[0]=='.') break;
setup();
}
if(checkPizza()==true) output();
else puts("No pizza can satisfy these requests.");
}
- 大众比萨
- 10.6 比萨 2408
- 假如有这样一场比萨
- 青岛外卖 教你做鲜虾里脊肉比萨
- 青岛外卖 教你做鲜虾里脊肉比萨
- 比萨中文离线地图App上线
- 记忆化搜索专题--nkoj3699送比萨
- 娱乐大众
- 大众小众
- 娱乐大众
- 大众密码学
- 大众点评
- 编写程序实现比萨制作。需求说明编写程序,接收用户输入的信息,选择需要制作的比萨。可供选择的比萨有:培根比萨和海鲜比萨。
- 大众“中国路,大众心”广告
- 大众“中国路,大众心”广告
- 使用JSF来构建在线比萨(pizza)订购系统
- JSF实例学习--比萨(pizza)订购系统
- 由可乐加比萨化学反应引发的联想
- 标题:C++中struct与class的区别是什么?
- 精通Struts(word版本)下载
- OpenLDAP 介绍及安装
- Eclipse 介绍
- 使用Ghost32.exe进行点对点计算机克隆
- 大众比萨
- 实战的差距
- ARP病毒入侵原理和解决方案
- DRM串起了内容产业链
- 怎样改变正在运行的exe文件的图标.
- 雾
- TOMCAT配置自动指向项目.doc
- 数字版权的最后一道防线—数字水印
- 少年中國說少年中國說 作者:梁啟超