UVA 565 565 Pizza Anyone? (深搜 +位运算)

  Pizza Anyone? 

You are responsible for ordering a large pizza for you and your friends. Each of them has told you what he wants on a pizza and what he does not; of course they all understand that since there is only going to be one pizza, no one is likely to have all their requirements satisfied. Can you order a pizza that will satisfy at least one request from all your friends?


The pizza parlor you are calling offers the following pizza toppings; you can include or omit any of them in a pizza:

Input CodeTopping
AAnchovies
BBlack Olives
CCanadian Bacon
DDiced Garlic
EExtra Cheese
FFresh Broccoli
GGreen Peppers
HHam
IItalian Sausage
JJalapeno Peppers
KKielbasa
LLean Ground Beef
MMushrooms
NNonfat Feta Cheese
OOnions
PPepperoni

Your friends provide you with a line of text that describes their pizza preferences. For example, the line

+O-H+P;

reveals that someone will accept a pizza with onion, or without ham, or with pepperoni, and the line

-E-I-D+A+J;

indicates that someone else will accept a pizza that omits extra cheese, or Italian sausage, or diced garlic, or that includes anchovies or jalapenos.

Input 

The input consists of a series of pizza constraints.

A pizza constraint is a list of 1 to 12 topping constraint lists each on a line by itself followed by a period on a line by itself.

A topping constraint list is a series of topping requests terminated by a single semicolon.

An topping request is a sign character (+/-) and then an uppercase letter from A to P.

Output 

For each pizza constraint, provide a description of a pizza that satisfies it. A description is the string `` Toppings:  " in columns 1 through 10 and then a series of letters, in alphabetical order, listing the toppings on the pizza. So, a pizza with onion, anchovies, fresh broccoli and Canadian bacon would be described by:

Toppings: ACFO

If no combination toppings can be found which satisfies at least one request of every person, your program should print the string

No pizza can satisfy these requests.

on a line by itself starting in column 1.

Sample 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;
.
+A+B+C+D;
+E+F+F+H;
+A+B-G;
+O+J-F;
+H+I+C;
+P;
+O+M+L;
+M-L+P;
.
+A+B+C+D;
+E+F+F+H;
+A+B-G;
+P-O;
+O+J-F;
+H+I+C;
+P;
+O;
+O+M+L;
-O-P;
+M-L+P;
.

Sample Output 

Toppings:
Toppings: CELP
No pizza can satisfy these requests.

题意:一个披萨有16种配料。现在有几个人要定一份披萨。每个人都有一定需求,+代表要哪种配料,-代表不要。

要找出一种披萨。来满足所有人至少一个需求。。如果找不到就输出No pizza can satisfy these requests.

思路:一共16种配料。选与不选每种配料2种选择,一共就是2^16种情况。暴力枚举。。结果超时了。。 因为每种披萨都要进行判断。判断的过程算进去就超时了。。没想出比较好的方法。。看到别人用位运算。。自己也试了下。结果就过了。。不过跑了500多MS。。不知道那些0.00几ms的大神怎么做的。。

位运算:把每个人需要与不需要,存成一个16位2进制数。然后在从0枚举到2 ^16 - 1代表每种披萨。如果有满足条件

他们的或运算会>0。。(关于位运算。稍微看下就能明白的)。。。然后就枚举直到有一种披萨符合条件。把该二进制数转换成相应披萨的字母输出。如果没有。就输出No pizza can satisfy these requests.

#include <stdio.h>
#include <string.h>

struct Q
{
    int yes;
    int no;
} q[10005];

int num = 0;
int sta;
int out[20];
char str[105];

int main()
{
    while (gets(str) != NULL)
    {
	if (str[0] == '.')
	{
	    for (sta = 0; sta < (1 << 16); sta ++)
	    {
		int i;
		for (i = 0; i < num; i ++)
		{
		    if ((q[i].yes & sta) || (q[i].no & (~sta)))
			continue;
		    else
			break;
		}
		if (i == num)
		    break;
	    }
	    int nnum = 0;
	    for (int i = 0; i < 16; i ++)
	    {
		if (sta & (1 << i))
		    out[nnum ++] = i + 'A';
	    }
	    if (sta == (1 << 16))
		printf("No pizza can satisfy these requests.\n");
	    else
	    {	
		printf("Toppings: ");
		for (int i = 0; i < nnum; i ++)
		    printf("%c", out[i]);
		printf("\n");
	    }
	    memset(q, 0, sizeof(q));
	    memset(out, 0, sizeof(out));
	    num = 0;
	    continue;
	}
	for (int i = 0; str[i] != ';'; i += 2)
	{
	    if (str[i] == '+')
		q[num].yes |= (1 << (str[i + 1] - 'A'));
	    if (str[i] == '-')
		q[num].no |= (1 << (str[i + 1] - 'A'));
	}
	num ++;
    }	
    return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值