翻煎饼 Stacks of Flapjacks
题意:本题意为煎饼排序,大的放在上面,小的放在下面(此题输入是从上到下输入的),为煎饼排序是通过一系列的“翻转”动作来完成的。翻转动作就是将一个小铲插到一叠煎饼中的某两个煎饼之间,然后用小铲将上面的所有煎饼翻转(即为将小铲上面的子栈倒转过来)。输出翻转的位置,即小铲上面子栈中最底下一个煎饼的位置号。
解题思路:此题读题的时间比写这题的时间久,本题的解题思路很简单,就是将一定的数组翻转过来,可以用到栈,本题也有一些小技巧,可以先将字符里边的数据先排序,然后找到每一个数字相对应的位置,同时为了简洁函数,可以在外面写一个翻转函数,直接调用就可以了。
代码:
1 #include<stdio.h> 2 #include<stack> 3 #include<string.h> 4 #include<algorithm> 5 #include<iostream> 6 using namespace std; 7 int a[50],b[50]; 8 stack<int> q; 9 int main(){ 10 freopen("in.txt","r",stdin); 11 int num=1; 12 while(scanf("%d",&a[num])!=EOF){ 13 memset(b,0,sizeof(b)); 14 while(getchar()!='\n'){ 15 scanf("%d",&a[++num]); 16 } 17 for(int i=1;i<=num;i++){ 18 printf("%d%c",a[i],i==num?'\n':' '); 19 } 20 for(int i=1;i<=num;i++){ 21 b[i]=a[i]; 22 } 23 sort(b+1,b+num+1); 24 for(int i=num;i>0;i--){ 25 if(a[i]==b[i]) continue; 26 else if(a[1]==b[i]){ 27 printf("%d ",num-i+1); 28 for(int j=1;j<=i;j++){ 29 q.push(a[j]); 30 } 31 for(int j=1;j<=i;j++){ 32 a[j]=q.top(); 33 q.pop(); 34 } 35 } 36 else{ 37 int pos; 38 for(int j=1;j<=i;j++){ 39 if(a[j]==b[i]){ 40 pos=j; 41 break; 42 } 43 } 44 printf("%d ",num-pos+1); 45 printf("%d ",num-i+1); 46 for(int j=1;j<=pos;j++){ 47 q.push(a[j]); 48 } 49 for(int j=1;j<=pos;j++){ 50 a[j]=q.top(); 51 q.pop(); 52 } 53 for(int j=1;j<=i;j++){ 54 q.push(a[j]); 55 } 56 for(int j=1;j<=i;j++){ 57 a[j]=q.top(); 58 q.pop(); 59 } 60 } 61 } 62 num=1; 63 printf("0\n"); 64 memset(a,0,sizeof(a)); 65 } 66 }
同时附上一位大神的代码:(代码出处:http://www.cnblogs.com/devymex/archive/2010/08/15/1799844.html)
1 #include <algorithm> 2 #include <iostream> 3 #include <iterator> 4 #include<stdio.h> 5 #include <deque> 6 #include <string> 7 #include <sstream> 8 using namespace std; 9 //主函数 10 int main(void) { 11 freopen("in.txt","r",stdin); 12 //循环处理输入的每组字符串。每次循环一轮要输出最后的0和换行 13 for (string strLine; getline(cin, strLine); cout << '0' << endl) { 14 //按要求回应输入的字符串行 15 cout << strLine << endl; 16 //构造字符串流,以遍转换为数字 17 istringstream iss(strLine); 18 //将字符串转为数字,逆序(最底的在最前)存储在Stack里 19 deque<int> Stack; 20 for (int nDiam; iss >> nDiam; Stack.push_front(nDiam)); 21 //从底依次上向进行翻转,保持i上面的都比i小 22 for (deque<int>::iterator i = Stack.begin(); i != Stack.end(); ++i) { 23 //找出i上面(包括i)的最大元素 24 deque<int>::iterator iMax = max_element(i, Stack.end()); 25 //如果最大元素就是i则继续(将i指向上面一个) 26 if (iMax != i) { //否则要进行需翻转操作 27 //如果最大的不在最上面,则需先翻转到最上面 28 if (iMax != Stack.end() - 1) { 29 reverse(iMax, Stack.end()); 30 //输出翻转的起点 31 cout << distance(Stack.begin(), iMax) + 1 << ' '; 32 } 33 //将最大的从最上面翻转到i的位置上 34 reverse(i, Stack.end()); 35 //输出翻转的起点 36 cout << distance(Stack.begin(), i) + 1 << ' '; 37 } 38 } 39 } 40 return 0; 41 }
本人觉得以上代码写得特别优美,特附上。