这道题目我第一次代码写的非常烂
主要烂在以下几点:
第一点:由于是边输入边判断,所以必须考虑判断完毕后,输入还没有完成的情况,导致了代码逻辑异常的复杂。(以后不可以边输入边判断)
第二点:虽然第一次理清了逻辑(写到纸上),但是这个逻辑是相当混乱的
贴上第一次写的很烂的代码
#include<cstdio> #include<stack> using namespace std; int num_coach; int now_coach; void read_order() { for(;;) { int N = 1; stack<int>Stack; int over =0; for(int i = 0;i < num_coach;i++) { scanf("%d",&now_coach); if(now_coach == 0) { return; } //printf("now_coach=%d\n",now_coach); if(!over) { if(!Stack.empty() && Stack.top() == now_coach) { Stack.pop(); continue; } while(N < now_coach) { Stack.push(N); N++; } if(N == now_coach) { N++; continue; } if(N > now_coach) { over =1; printf("No\n"); } } } if(!over) { printf("Yes\n"); } } } int ain() { #ifdef local freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif while(scanf("%d",&num_coach) == 1 && num_coach) { read_order(); printf("\n"); } return 0; }
下面对上述的问题进行改进:
改进的地方有:
1.把数据都输入完毕后才开始判断
2.在纸上把这种多次判断的逻辑理清楚以后,再去编代码实现,这一点也是我之前总是出错的原因
3.这道题的输入格式非常的奇怪,每个case下面需要判断的组数不确定,所以输入的格式应该是一个case两个循环,一组判定完毕后,跳出内层循环,遇到判定条件后直接退出这个case,非常适合用一个函数来实现。
下面贴出我写的改进的代码:
#include<cstdio> #include<stack> using namespace std; int num_coach; int now_coach; int order[1005]; void read_order() { for(;;) { for(int i = 1;i <= num_coach;i++) { scanf("%d",&now_coach); if(now_coach == 0) { return; } order[i] = now_coach; } stack<int>Stack; int A = 1,B = 1; for(;B <= num_coach;) { if(A == order[B]) { A++; B++; } else if(!Stack.empty() && Stack.top() == order[B]) { Stack.pop(); B++; } else if(A > order[B]) { printf("No\n"); break; } else { Stack.push(A); A++; } } if(B == (num_coach + 1)) printf("Yes\n"); } } int main() { #ifdef local freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); #endif while(scanf("%d",&num_coach) == 1 && num_coach) { read_order(); printf("\n"); } return 0; }
上面的read_order()函数就是我之前说的输入的格式问题。