UVa 565 Pizza Anyone?

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=109&page=show_problem&problem=506

题意:一群人想点一个Pizza,每个人都提出一些条件,求出一个Pizza满足每个人至少一个要求。

分析:一共16中物品,每种放或不放,最多2^16中情况,用二进制表示一下就行。

我做的有些麻烦了,一开始没加剪枝1,TLE,加上剪枝1过的也很悬,2.440s。

剪枝1:如果这种选法选择了未出现的物品,则不符合条件。

剪枝2:如果满足了这个人的某一个条件,则不必再看其他条件是否满足

剪枝3:如果某个人所有的条件都不满足,则这种物品的选法不符合条件。

剪枝4:如果找到一个合适的情况,就不必在向下寻找

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cctype>
 5 
 6 char str[1010][110];
 7 char ans[1010];
 8 bool vis[30];
 9 int cnt;
10 
11 bool Judge( int n )
12 {
13     for ( int i = 0; i < 17; ++i )
14     if ( !vis[i] && ( ( 1 << i ) & n ) ) return false;
15     return true;
16 }
17 
18 int main()
19 {
20     cnt = 0;
21     while ( gets(str[cnt]) != NULL )
22     {
23         memset( vis, false, sizeof(vis) );
24         while ( str[cnt][0] != '.' )
25         {
26             int k = 0;
27             while ( str[cnt][k] != '\0' )
28             {
29                 if ( isalpha( str[cnt][k] ) )
30                     vis[ str[cnt][k] - 'A' ] = true;
31                 ++k;
32             }
33             gets(str[++cnt]);
34         }
35 
36         int i = 0;
37         bool find = false;
38         for ( ; i <= ( 1 << 16 ); ++i )
39         {
40             if ( !Judge( i ) ) continue;      //剪枝1
41             for ( int j = 0; j < cnt; ++j )
42             {
43                 int k = 0;
44                 find = false;
45                 while ( str[j][k] != '\0' )
46                 {
47                     if ( isalpha(str[j][k]) )
48                     {
49                         if ( str[j][k - 1] == '+' && ( i & ( 1 << (str[j][k] - 'A') ) ) )
50                         {
51                             find = true;
52                             break;                            //剪枝2
53                         }
54                         else if ( str[j][k - 1] == '-' && ( i & ( 1 << (str[j][k] - 'A') ) ) == 0 )
55                         {
56                             find = true;
57                             break;                            //剪枝2
58                         }
59                     }
60                     ++k;
61                 }
62                 if ( !find ) break;                           //剪枝3
63             }
64             if ( find ) break;                                //剪枝4
65         }
66 
67         if ( !find )
68         {
69             puts("No pizza can satisfy these requests.");
70             cnt = 0;
71             continue;
72         }
73 
74         int len = 0;
75         for ( int k = 0; k < 17; ++k )
76         {
77             if ( ( 1 << k ) & i )
78                 ans[ len++ ] = k + 'A';
79         }
80         ans[len] = '\0';
81 
82         printf( "Toppings:" );
83         if ( len == 0 ) putchar('\n');
84         else printf( " %s\n", ans );
85 
86         cnt = 0;
87     }
88     return 0;
89 }
原文地址:https://www.cnblogs.com/GBRgbr/p/2728476.html