题意:构造Pascal的排序程序。初看是写Pascal程序,不了解的以为会很难,但其实程序的大部分是固定的,直接printf就可以,主要在于写比较的if-else部分。
思路:看sample out可以大概知道程序的构成,其他部分直接输出,主要写比较的部分。比较的时候,可以看成两个集合,A是已排好序的,S是全集,cur是从左到右扫描S的当前位置。用递归写的,前半部分是当当前位置cur到达n时,即可以输出了;剩下的是如何填写当前位置cur以及维持A是已排好序的这个性质。将新元素S[cur]从A的最右端往左开始比较,如果新元素S[cur]较大,则直接放在A的当前元素的右边即i+1位置;否则,新元素较小,将A的当前元素右移一位,即拷贝到i+1位置,然后新元素继续与左边一个元素比较。还有一点就是因为数组传到函数后会改变内容的,所以在每次传函数前,新构造一个数组B,复制A数组的内容然后输出。否则的话,不用B数组,直接传A数组,对于两个元素没问题,对于三个元素的话,在if
a<b 这个部分是正确的,而在这个条件开启的else里面就会发现没有a了,而又两个c,这就是因为递归虽然返回了,但数组A已被修改,第一位a已被修改为c。另外,题目没有说缩进的要求,果然提交后发现每行的缩进是没有要求的,只要保证writeln语句单独在一行即可。
本地修改多次,一次AC,取得当前所做所有题目中最高排名74,之前最好是11234题排79。就是做得太慢了,想了好久才会,开始也在考虑缩进的问题、毕竟sample out中第一个if-else和后来的if-else缩进是不同的。。。
Code:
#include<stdio.h> #include<string.h> void solve(int n); void compare(int n,char *A,char *S,int cur); char str[]="abcdefghijklmn"; int main() { int m; scanf("%d",&m); while(m-->0) { int n; scanf("%d",&n); solve(n); if(m) printf("\n"); } return 0; } void solve(int n) { printf("program sort(input,output);\n"); printf("var\n"); for(int i=0;i<n-1;++i) printf("%c,",str[i]); printf("%c : integer;\n",str[n-1]); printf("begin\n"); printf(" readln("); for(int i=0;i<n-1;++i) printf("%c,",str[i]); printf("%c);\n",str[n-1]); char A[10]; compare(n,A,str,0); printf("end.\n"); } void compare(int n,char *A,char *S,int cur) { if(cur==n) { printf("writeln("); for(int i=0;i<cur-1;++i) printf("%c,",A[i]); printf("%c)\n",A[cur-1]); return ; } for(int i=cur-1;i>=0;--i) { printf(" if %c < %c then\n",A[i],S[cur]); A[i+1]=S[cur]; char B[10]; strcpy(B,A); compare(n,B,S,cur+1); printf("else\n"); A[i+1]=A[i]; A[i]=S[cur]; //compare(n,A,S,cur+1); } A[0]=S[cur];//初始cur=0时 char B[10]; strcpy(B,A); compare(n,B,S,cur+1); }
时间: 2024-10-10 23:29:04