Aizu/Aoj 0033 Ball
题目大意: 有编号1到10共10个球,从上方丢下去,入口处可以选择进入左边或者右边,最后10个球全部落下去后如果左右两侧都是从小到大的顺序,则输出YES;否则输出NO。
题目原本的标签枚举,复杂度是2^10,,,很容易水过。我这里说的是用贪心的方法,直接扫一遍O(10)复杂度: 设两个栈 模拟左右两个管; 对于每一个球有以下几种处理情况:
1、如果两个栈都为空,就往任意一个栈里放入小球
2、如果当前小球编号同时小于两个栈的栈顶小球编号,则直接输出"NO"
3、如果当前小球编号比其中一个栈的栈顶小球编号小,则放入另一个栈中
4、如果仅有一个栈空或都不为空,就判断当前小球编号是否为其中一个栈的栈顶小球编号数+1,是的话就放入那个栈内
5、当前小球编号都不为两个栈栈顶的小球编号数+1,那就判断哪个栈的栈顶小球编号数距其最近,就放入哪个栈
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <cstdlib> 7 #include <cctype> 8 #include <queue> 9 #include <stack> 10 #include <map> 11 #include <vector> 12 #include <set> 13 #include <utility> 14 #define ll long long 15 #define inf 0x3f3f3f3f 16 using namespace std; 17 18 int a[15]; 19 int main() 20 { 21 //freopen("input.txt","r",stdin); 22 int n; 23 scanf("%d",&n); 24 while(n--) 25 { 26 for(int i=0; i<10; i++) 27 scanf("%d",&a[i]); 28 // 29 stack<int> sl,sr; 30 sl.push(a[0]); 31 // 32 bool flag=true; 33 for(int i=1; i<10; i++) 34 { 35 if(!sr.empty()) 36 { 37 if(a[i]<sl.top()&&a[i]<sr.top()) 38 { 39 flag=false; 40 break; 41 } 42 else 43 { 44 if(a[i]==sl.top()+1) 45 sl.push(a[i]); 46 else if(a[i]==sr.top()+1) 47 sr.push(a[i]); 48 else if(a[i]<sl.top()) 49 sr.push(a[i]); 50 else if(a[i]<sr.top()) 51 sl.push(a[i]); 52 else 53 { 54 if((a[i]-sl.top())<(a[i]-sr.top())) 55 sl.push(a[i]); 56 else 57 sr.push(a[i]); 58 } 59 } 60 } 61 else 62 { 63 if(a[i]==sl.top()+1) 64 sl.push(a[i]); 65 else 66 sr.push(a[i]); 67 } 68 } 69 // 70 if(flag) 71 printf("YES\n"); 72 else 73 printf("NO\n"); 74 } 75 return 0; 76 }