射击游戏---栈与子弹
1.射击游戏
Description
小明很喜欢玩射击游戏。他刚考完了数据结构期末考试,感觉不错,于是又来到了射击娱乐场放松一下。和上次一样,先从老板那租了一把步枪和装有N发子弹的弹夹。这里,再把规则说一遍。在射击的过程中,小明每次都有两种选择:从弹夹中取出一颗子弹上膛,或者打一发子弹出去。注意:所有的子弹都从枪口上膛。小明感觉这有点像《数据结构》课程中的“栈”的特点。因此在打完了这N发子弹之后,他想验证一下这些子弹打出来的顺序是不是真的满足“栈”的特性。假设N颗子弹的编号为1,2,…,N。子弹从弹夹中取出的顺序也是从1到N,这里N = 10。给定一个子弹被打出的顺序,你可以帮小明验证它满不满足“栈”的打出顺序吗?
分析:这里需要考虑的是栈的出入问题,给我一个序列,我就只需要看模拟一下这个序列在整个出栈入栈的过程中符不符合就可以了。我们可以以下面这几条为思路:
维护两个指针A、B,A表示子弹上膛的指针,B表示打出的子弹的指针,维护一个堆栈模拟弹夹;
分四种情况讨论:
(1)如果A指针和B指针所指内容相同,那么A和B递增,否则;
(2)如果B指针指的内容和栈顶相同,那么B递增,栈顶弹出,否则;
(3)如果A指针还合法,把A的当前值压入堆栈,A递增,否则;
(4)这个子弹序列是得不到的。
根据思路可以写出代码如下:
1 #include <iostream> 2 #include <stdio.h> 3 #include <stack> 4 5 using namespace std; 6 7 bool judgeSeq(int* stack_, int len) { 8 stack<int> bulletIn; 9 int A = 1, B = 1; 10 11 while (B <= len) { 12 //相当于入栈后马上出栈 13 if (stack_[B] == A) { 14 A++; 15 B++; 16 } else if (!bulletIn.empty() && bulletIn.top() == stack_[B]) { 17 //和栈顶元素相同,那么就将栈顶元素出栈,同时B指向下一个子弹 18 bulletIn.pop(); 19 B++; 20 } else if (A <= len) { 21 //B指向的元素不是刚要入栈的元素也不是栈顶元素,那么就 22 //继续将未入栈的元素入栈看看B对应的子弹是否在子弹夹里面 23 bulletIn.push(A); 24 A++; 25 } else{ 26 //查找完子弹夹没有发现B对应的子弹,栈最上面的元素又 27 //不是对应的子弹,那么久无法在此时打出对应于B的子弹 28 //所以此时的序列就是一个错误的序列 29 return false; 30 } 31 } 32 return true; 33 } 34 35 int main(int argc, char const *argv[]) 36 { 37 int sizeOfTheStack; 38 int *stack_; 39 char commend; 40 do { 41 printf("Enter the size of the stack:"); 42 scanf("%d", &sizeOfTheStack); 43 printf("Enter a list of number as the bullet secquence:\n"); 44 stack_ = new int[sizeOfTheStack + 1]; 45 for (int i = 1; i <= sizeOfTheStack; i++) 46 scanf("%d", &stack_[i]); 47 48 judgeSeq(stack_, sizeOfTheStack) == 1 ? printf("Yes\n") : printf("No\n"); 49 50 printf("again?(Y/N): "); 51 scanf("\n%c", &commend); 52 53 delete []stack_; 54 } while (commend == 'Y' || commend == 'y'); 55 return 0; 56 }