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 }