aoj 0033 Ball【dfs/枚举】
有一个形似央视大楼(Orz)的筒,从A口可以放球,放进去的球可通过挡板DE使其掉进B裤管或C裤管里,现有带1-10标号的球按给定顺序从A口放入,问是否有一种控制挡板的策略可以使B裤管和C裤管中的球从下往上标号递增。
输入:
第一行输入数据组数N。接下来N行为N组具体数据,每组数据中有10个整数,代表球的放入顺序。
输出:
对于每组数据,若策略存在,输出YES;若不存在,输出NO
【分析】:因为每个球都有向左或者向右两种状况,数据量比较小,可以直接进行dfs 全部的情况进行遍历。
【代码】:
#include <bits/stdc++.h> using namespace std; int x[15],l[15],r[15]; int flag; void dfs(int i,int L,int R) { if(i>10) { flag = 1; return; } if(flag) { return; } if(x[i]>l[L-1]) { l[L] = x[i]; dfs(i+1,L+1,R); } if(x[i]>r[R-1]) { r[R] = x[i]; dfs(i+1,L,R+1); } } int main() { int t; scanf("%d",&t); while(t--) { for(int i=1;i<=10;i++) { scanf("%d",&x[i]); } flag = 0; dfs(1,1,1); if(flag) { puts("YES");//不要加\n 因为puts输出字符串隐含了换行 } else { puts("NO"); } } return 0; } /* 2 3 1 4 2 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1 */
#include<cstdio> #include<cstring> int a[15], l[15], r[15], t, i, j, lc, rc, cnt; bool vis[15], flag; bool solve() { for (i = 0; i < 1024; ++i) { memset(l, 0, sizeof(l)); memset(r, 0, sizeof(r)); lc = rc = 0; for (cnt = 0, j = i; cnt < 10; ++cnt, j >>= 1) { if (j & 1) l[lc++] = a[cnt]; else r[rc++] = a[cnt]; } flag = true; for (j = 1; j < lc; ++j) if (l[j] < l[j - 1]) { flag = false; break; } if (flag) for (j = 1; j < rc; ++j) if (r[j - 1] > r[j]) { flag = false; break; } if (flag) return true; } return false; } int main() { scanf("%d", &t); while (t--) { memset(vis, 0, sizeof(vis)); for (i = 0; i < 10; ++i) scanf("%d", &a[i]); puts(solve() ? "YES" : "NO"); } return 0; }