AOJ -0033 Ball(DFS)

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=22516

一道需要思考的搜索题。

题意:十个球按给定顺序从图中所示容器中下落,然后挡板可以让球落在左边或者右边,问给定球的顺序,是否存在两边从低到高都是递增的情况。

解1:只要给定的球能够分成两个递增的序列,那么一定是满足条件的,用dfs可以找出以第一个球为首的递增序列,把其标记,然后判断剩下的球是不是也构成一个递增序列。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <vector>
 5 #include <cstring>
 6 #include <string>
 7 #include <algorithm>
 8 #include <string>
 9 #include <set>
10 #include <functional>
11 #include <numeric>
12 #include <sstream>
13 #include <stack>
14 #include <map>
15 #include <queue>
16 
17 #define CL(arr, val)    memset(arr, val, sizeof(arr))
18 
19 #define ll long long
20 #define inf 0x7f7f7f7f
21 #define lc l,m,rt<<1
22 #define rc m + 1,r,rt<<1|1
23 #define pi acos(-1.0)
24 
25 #define L(x)    (x) << 1
26 #define R(x)    (x) << 1 | 1
27 #define MID(l, r)   (l + r) >> 1
28 #define Min(x, y)   (x) < (y) ? (x) : (y)
29 #define Max(x, y)   (x) < (y) ? (y) : (x)
30 #define E(x)        (1 << (x))
31 #define iabs(x)     (x) < 0 ? -(x) : (x)
32 #define OUT(x)  printf("%I64d
", x)
33 #define lowbit(x)   (x)&(-x)
34 #define Read()  freopen("a.txt", "r", stdin)
35 #define Write() freopen("dout.txt", "w", stdout);
36 #define maxn 1000000000
37 #define N 110
38 using namespace std;
39 
40 int arr[15],used[15];
41 
42 void dfs(int pre,int cur)
43 {
44     if(cur<10&&arr[pre]<arr[cur])
45     {
46         used[cur]=1;
47         dfs(cur,cur+1);
48     }
49     else if(cur<10&&arr[pre]>=arr[cur])
50         dfs(pre,cur+1);
51 }
52 int main()
53 {
54     //freopen("a.txt","r",stdin);
55     int t;
56     scanf("%d",&t);
57     while(t--)
58     {
59         bool judge=false;
60         for(int i=0;i<10;i++)
61             scanf("%d",&arr[i]);
62         for(int i=0;i<10;i++)
63         {
64             memset(used,0,sizeof(used));
65             used[i]=1;
66             dfs(i,i+1);
67             int pre=0;
68             judge=false;
69             for(int j=0;j<10;j++)
70             {
71                 if(!used[j])
72                 {
73                     if(pre>=arr[j])
74                     {
75                         judge=true;
76                         break;
77                     }
78                     pre=arr[j];
79                 }
80             }
81             if(!judge)
82             {
83                 printf("YES
");
84                 break;
85             }
86         }
87         if(judge) printf("NO
");
88     }
89    return 0;
90 }
View Code

解2:当然可以采用二进制枚举(第一次知道这个算法),每个球要么落在左边要么在右边,10个球总共2的10次方=1024种状态。0-2013每一个数都代表一种状态。不断枚举直到找到合适的为止。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <vector>
 5 #include <cstring>
 6 #include <string>
 7 #include <algorithm>
 8 #include <string>
 9 #include <set>
10 #include <functional>
11 #include <numeric>
12 #include <sstream>
13 #include <stack>
14 #include <map>
15 #include <queue>
16 
17 #define CL(arr, val)    memset(arr, val, sizeof(arr))
18 
19 #define ll long long
20 #define inf 0x7f7f7f7f
21 #define lc l,m,rt<<1
22 #define rc m + 1,r,rt<<1|1
23 #define pi acos(-1.0)
24 
25 #define L(x)    (x) << 1
26 #define R(x)    (x) << 1 | 1
27 #define MID(l, r)   (l + r) >> 1
28 #define Min(x, y)   (x) < (y) ? (x) : (y)
29 #define Max(x, y)   (x) < (y) ? (y) : (x)
30 #define E(x)        (1 << (x))
31 #define iabs(x)     (x) < 0 ? -(x) : (x)
32 #define OUT(x)  printf("%I64d
", x)
33 #define lowbit(x)   (x)&(-x)
34 #define Read()  freopen("a.txt", "r", stdin)
35 #define Write() freopen("dout.txt", "w", stdout);
36 #define maxn 1000000000
37 #define N 110
38 using namespace std;
39 
40 int main()
41 {
42     //freopen("a.txt","r",stdin);
43     int t;
44     int arr[15],l[15],r[15];
45     scanf("%d",&t);
46     while(t--)
47     {
48        int i,j,cnt;
49        bool flag;
50        for(i=0;i<10;i++) scanf("%d",&arr[i]);
51        for(i=0;i<1024;i++)
52        {
53            int x=0,y=0;
54            for(cnt=0,j=i;cnt<10;cnt++,j>>=1)
55            {
56                if(j&1) l[x++]=arr[cnt];
57                else r[y++]=arr[cnt];
58            }
59             flag=true;
60            for(j=1;j<x;j++)
61            {
62                if(l[j]<l[j-1]) {flag=false;break;}
63            }
64            if(flag)
65            {
66                for(j=1;j<y;j++)
67                {
68                    if(r[j]<r[j-1]) {flag=false;break;}
69                }
70            }
71            if(flag) {printf("YES
");break;}
72        }
73        if(!flag) printf("NO
");
74     }
75    return 0;
76 }
View Code
原文地址:https://www.cnblogs.com/nowandforever/p/4373940.html