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\n", 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\n");
84                 break;
85             }
86         }
87         if(judge) printf("NO\n");
88     }
89    return 0;
90 }

解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\n", 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\n");break;}
72        }
73        if(!flag) printf("NO\n");
74     }
75    return 0;
76 }

时间: 2024-10-14 17:43:05

AOJ -0033 Ball(DFS)的相关文章

AOJ 0033 Ball【DFS】

有一个筒,从A口可以放球,放进去的球可通过挡板DE使其掉进B管或C管里,现有带1-10标号的球按给定顺序从A口放入,问是否有一种控制挡板的策略可以使B管和C管中的球从下往上标号递增. 输入: 第一行输入数据组数N.接下来N行为N组具体数据,每组数据中有10个整数,代表球的放入顺序. 输出: 对于每组数据,若策略存在,输出YES:若不存在,输出NO 解法1:DFS 思路:每次判断当前小球是否大于左边容器的最上端的小球,如果可以就放,否则再去看右边的.一旦发现左右两边都不能放,那就只能判定是NO了.

AOJ 0033 ball+AOH 0118Property Distribution (DFS)

Description タナカ氏が HW アールの果樹園を残して亡くなりました.果樹園は東西南北方向に H×W の区画に分けられ.区画ごとにリンゴ.カキ.ミカンが植えられています.タナカ氏はこんな遺言を残していました. 果樹園は区画単位でできるだけ多くの血縁者に分けること.ただし.ある区画の東西南北どれかの方向にとなりあう区画に同じ種類の果物が植えられていた場合は.区画の境界が分からないのでそれらは 1 つの大きな区画として扱うこと. 例えば次のような 3x10 の区画であれば(リはリンゴ.カは

AOJ 0033 Ball 题解 《挑战程序设计竞赛》

题目:Aizu - 0033 思路:二进制枚举,用了昨天学到的2^N以及与运算方法枚举. 1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 5 using namespace std; 6 7 int n; 8 int ball[10]; 9 vector<int> l; 10 vector<int> r; 11 12 bool solve() { 13 bool

AOJ 0033 Ball

题意 题目我截图下来了,我大致解释下.有编号1到10共10个球,从上方丢下去,入口处可以选择进入左边或者右边,最后10个球全部落下去后如果左右两侧都是从小到大的顺序,则输出YES:否则输出NO. 代码 一开始我先测试了一下自己理解的题意是不是对的: #include <iostream> #include <vector> using namespace std; int main() { vector<int> left; vector<int> righ

AOJ 0033

Ball 可以用dfs,不过发现用一个循环就可以搞定. 1 #include <iostream> 2 using namespace std; 3 int a[11], n; 4 int main(){ 5 cin >> n; 6 while(n--){ 7 for(int i = 0; i < 10; i ++) cin >> a[i]; 8 int c = 0, b = 0, flag = 1; 9 for(int i = 0; i < 10; i +

POJ 1979 POJ 3009 AOJ 0033 AOJ 0118 [搜索类题目][0033贪心模拟]

/** POJ 1979 BFS */ #include <stdio.h> #include <string.h> #include <iostream> #include <queue> using namespace std; const int N = 20 + 5; int mp[N][N]; int sx,sy; int n, m; int vis[3000]; int dirx[] = {0, 1, 0, -1}; int diry[] = {

nomasp 博客导读:Android、UWP、Algorithm、Lisp(找工作中……

Profile Introduction to Blog 您能看到这篇博客导读是我的荣幸.本博客会持续更新.感谢您的支持.欢迎您的关注与留言.博客有多个专栏,各自是关于 Android应用开发 .Windows App开发 . UWP(通用Windows平台)开发 . SICP习题解 和 Scheme语言学习 . 算法解析 与 LeetCode等题解 .而近期会加入的文章将主要是算法和Android.只是其他内容也会继续完好. About the Author 独立 Windows App 和

挑战程序设计竞赛 2.1 最基础的“穷竭搜索”

[Summarize] 1.划分为两堆的无序模型可以利用二进制枚举, 而划分为两堆的有序模型可以枚举全排列取定长 2.当搜索终态唯一时可考虑逆向搜索 POJ 1979:Red and Black /* 一个矩形的屋子里有一个人,他可以踩黑格子,但是不能踩红格子, 他现在站在一个黑格子上,告诉你房间的布局, 这个人可以向上下左右四个方向移动,问这个人最多能到达的格子数 */ #include <cstdio> #include <cstring> using namespace st

十三 十四周总结

1 //十三周总结 2 //在看挑战程序设计的第二章和第三章的第一节 3 //二分 4 //1.从一个 有序的数组里面查找某一个值 5 int pos=lower_bound(a,a+n,key)-a;//返回的pos是大于等于键值的第一个位置 6 int pos=upper_bound(a,a+n,key)-a;//返回的pos是严格大于键值的第一 个位置 7 //2.判断一个解是否可行 8 //1)一般应该是先确定上界,下界,一个判断解是否可行的ok函数来找 9 //2) 看书上写的,输出小