题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=46
题目描述:
Meta-Loopless Sorts |
For those unfamiliar with Pascal syntax, the example at the end of this problem completely defines the small subset of Pascal needed.
1 3
program sort(input,output); var a,b,c : integer; begin readln(a,b,c); if a < b then if b < c then writeln(a,b,c) else if a < c then writeln(a,c,b) else writeln(c,a,b) else if a < c then writeln(b,a,c) else if b < c then writeln(b,c,a) else writeln(c,b,a) end.
题意:写一个如上述 输出形式的排序程序,并且这里面还包含了 排序的结果。
题解:一开始想到用打表 毕竟只有8个字母要排序,后来想想不用打表 也可以很简单地搞出来。
我是用插空的思想来做的: 考虑只有1个字母 a 那么 用字母a去 插空 一个空集 及只有1个空可以插 那么 答案是 a
考虑有 2个字母 a,b 那么 a只有 一种插法 在递归到b 用b去插剩余的集合(只有a),那么有两个空可以插 (_a_)那么 答案是 ab ,ba
考虑三个字母 a,b,c 这里 由于前面已经讨论好a和b的插法了 直接看c 的插空 就是 (_a_b_)和 (_b_a_) 这样可以得到6个答案。
。。。。。。后面以此类推
如何将刚才的分析对应于程序的书写呢, 在此用3个字母的做样例说明:
首选考虑a的插法 程序中是没有体现的 那么直接考虑 b的插空 程序中的体现是 if a < b then 和 对应的 else 而这两条语句分别对应的是b插在a后面 和 b插在a前面 两个动作
然后 看下一级的c 以此类推 内推 分别是 c插 最后面 , c插 中间 和 c插在最前面。
以上:
按照这样的插空规律可以写出一个递归的程序。
代码:
/* topcoder codeforce acm */ #include<iostream> #include<stdio.h> #include<stdlib.h> #include<algorithm> #include<string> #include<vector> using namespace std; int T=0,N=0; char ch[10]={'a','a','b','c','d','e','f','g','h','i'}; vector<int> List; /*print the 2*n ' '*/ int PrintIndent(int n) { int m=n+n; int i=0; for(i=0;i<=m-1;i++) { printf(" "); } return(0); } /*if else recursive,the n is the index of the ch not the List*/ int IfElse(char c,int n) { if(n>N) { PrintIndent(n-1); printf("writeln("); int i=0; printf("%c",List[0]); for(i=1;i<=N-1;i++) { printf(",%c",List[i]); } printf(")\n"); } else { int i=List.size()-1;//the pointer to the end of the vector //if structure PrintIndent(n-1); printf("if "); printf("%c < %c",List[i],c); printf(" then\n"); //if's action List.insert(List.begin()+i+1,c);//insert the empty blank IfElse(ch[n+1],n+1); List.erase(List.begin()+i+1);//because of the recursive we should recover for the present level's state i--; //else if structure for(;i>=0;i--) { PrintIndent(n-1); printf("else if "); printf("%c < %c",List[i],c); printf(" then\n"); //else if action List.insert(List.begin()+i+1,c); IfElse(ch[n+1],n+1); List.erase(List.begin()+i+1); } //else structure i=0; PrintIndent(n-1); printf("else\n"); //else action List.insert(List.begin()+i,c); IfElse(ch[n+1],n+1); List.erase(List.begin()+i); } return(0); } /*for test*/ int test() { return(0); } /*main process*/ int MainProc() { scanf("%d",&T); while(T--) { //intialize the vector List.clear(); List.push_back('a'); scanf("%d",&N); printf("program sort(input,output);\nvar\na"); int i=0; for(i=2;i<=N;i++) { printf(",%c",ch[i]); } printf(" : integer;\n"); //the start of the program printf("begin\n"); PrintIndent(1); printf("readln(a"); for(i=2;i<=N;i++) { printf(",%c",ch[i]); } printf(");\n"); //recursive if else structure IfElse(ch[2],2); //end of the program printf("end.\n"); if(T>0) { printf("\n"); } } return(0); } int main() { MainProc(); return(0); }