hdu 4524 郑厂长系列故事——逃离迷宫 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4524

    一开始看题目,以为很难,其实是自己吓唬自己.....

    题目有句话要特别注意:如果右边没有箱子或者右边的箱子已经消失了,则无法操作当前的箱子,这是解题的关键!根据这个条件,比较序列中紧挨着的前后两个数(假设是i、j,j=i+1),要分三种情况讨论:1、相等(a[i] = a[j])。这时,两个数都变成0,下一个操作数是a[j]的下一个数,也就是i+2的位置  2、a[i] > a[j],此时肯定不符合题目条件,因为在当前箱子还没消失但右边箱子已经消失的情况下,是无法操作当前箱子的,此时最后肯定有箱子存在。  3、a[i]<a[j]。这时后一个箱子a[j]被点击的数字会改变,此时a[j]里的数要被覆盖。

     有两个细节让我wa了几次:1、i 的结束标志最好是n-2,这样的j(j=i+1)不用每次处理都要判断是否越界。(如果是i=n-1,会多了很多繁琐的判断) 2、当序列中的最后两个数相等的时候(例如(1、2、3、4、2),最后会变成(0,0, 0,2,2)),此时由于执行了a[i] = a[j]这个条件里面的操作i++,不会执行a[j] > a[i],此时a[j]不会被新的次数(a[j]-a[i] = 0)覆盖,也就是说a[j] != 0,但是明显这样是可以消去所有的箱子的!!所以a[i] = a[j]里面要加特判,a[j]要设为0。如果不是这种情况,即序列中的最后的一个数a[j] != 0,说明不能消去所有箱子。具体代码如下:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 const int MAXN = 1000000 + 5;
 5 int a[MAXN];
 6 
 7 int main()
 8 {
 9     int T, i, j, n, flag;
10     while (cin >> T)
11     {
12         while (T--)
13         {
14             cin >> n;
15             for (i = 0; i < n; i++)
16                 cin >> a[i];
17             flag = 1;
18             for (i = 0; i < n-1; i++)
19             {
20                 j = i+1;
21                 if (a[i] > a[j])
22                 {
23                     flag = 0;
24                     break;
25                 }
26                 else if (a[i] == a[j])
27                 {
28                     i++;         //再结合外循环的i++,实质上下一次操作的位置是i+2
29
a[j] = 0; //关键1,为了处理序列中最后两个数相同的情况 30 } 31 else 32 { 33 a[j] = a[j] - a[i]; 34 } 35 } 36 if (a[j]) //关键2,也是为了处理序列中最后两个数相同的情况 37 flag = 0;//序列中最后一个数不为0,说明不能消去所有箱子
38
if (flag) 39 printf("yeah~ I escaped ^_^\n"); 40 else 41 printf("I will never go out T_T\n"); 42 } 43 } 44 return 0; 45 }

 

posted @ 2013-05-04 22:10  windysai  阅读(183)  评论(0编辑  收藏  举报