AOJ0033
Appoint description:
Description
図のように二股に分かれている容器があります。1 から 10 までの番号が付けられた10 個の玉を容器の開口部 A から落とし、左の筒 B か右の筒 C に玉を入れます。板 D は支点 E を中心に左右に回転できるので、板 D を動かすことで筒 B と筒 C のどちらに入れるか決めることができます。
開口部 A から落とす玉の並びを与えます。それらを順番に筒 B 又は筒 Cに入れていきます。このとき、筒 B と筒 C のおのおのが両方とも番号の小さい玉の上に大きい玉を並べられる場合は YES、並べられない場合は NO と出力するプログラムを作成してください。ただし、容器の中で玉の順序を入れ替えることはできないものとします。また、続けて同じ筒に入れることができるものとし、筒 B, C ともに 10 個の玉がすべて入るだけの余裕があるものとします。
Input
複数のデータセットが与えられます。1行目にデータセット数 N が与えられます。つづいて、N 行のデータセットが与えられます。各データセットに 10 個の番号が左から順番に空白区切りで与えられます。
Output
各データセットに対して、YES または NO を1行に出力して下さい。
Sample Input
2 3 1 4 2 5 6 7 8 9 10 10 9 8 7 6 5 4 3 2 1
Output for the Sample InputYES
NO
:
题意:如图所示,十个带有数字的球从上到下依次落下,你可以自由控制挡板D,问是否可以使B,C两管的球都满足球上的数字由下到上依次递增
分析:
基础的二进制枚举。
只需要枚举每个球在哪一个管子里面,然后判断最终的两个管子是否满足要求就可以了。
1 #include <iostream> 2 using namespace std; 3 int arr[10]; 4 int A[10],B[10]; 5 bool check(int* a,int len){ 6 for(int i = 1 ; i < len ; i++)if(a[i] < a[i - 1]) return 0; 7 return 1; 8 } 9 int main(){ 10 int T; cin >> T; 11 while(T--){ 12 for(int i = 0 ; i < 10 ; i++) cin >> arr[i]; 13 // 枚举二进制状态 14 bool flag = false; 15 for(int j = 1 ; j < (1 << 10) - 1 ; j++){ 16 int i1 = 0,i2 = 0,k = j; 17 for(int i = 0 ; i < 10 ; i++){ 18 if(k & 1) A[i1++] = arr[i]; 19 else B[i2++] = arr[i]; 20 k >>= 1; 21 } 22 if(check(A,i1) && check(B,i2)){ 23 flag = true; 24 break; 25 } 26 } 27 if(flag) cout << "YES" << endl; 28 else cout << "NO" << endl; 29 } 30 return 0; 31 }