对于不了解的规律题要跳出来从全局看规律。
今天解决了UVa 110 Meta-Loopless Sort。这道题的关键在于生成全排列的同时也需要确定如何进行比较可以得到此种全排列。生成全排列的方法有很多,但是有一种方法最适合此题:
假设我们获得了1~n的全排列,如何获得1~n+1的全排列?对于每个1~n的全排列x(1), x(2), ... x(n),可以看作该排列中有n+1个空位,即,<slot>, x(1), <slot>, x(2), <slot>, ...., x(n), <slot>,于是把x(n+1)分别放入这n+1个空位可以得到从x(1), ... x(n)生成的所有1~n+1的全排列。同时,放入某个空位的同时也就决定了x(n+1)和每个元素的大小关系:
因为有x(1), x(2), ..., x(n),因此有x(1) <= x(2) <= x(3) .... <= x(n),则
x(n) < x(n+1), 则插入生成的排列为x(1), x(2), ..., x(n), x(n+1)
否则,如果x(n-1) < x(n+1), 则插入生成的排列为x(1), x(2), ..., x(n-1), x(n+1), x(n)
....
否则,(此时x(n+1) < x(1)),因此排列为x(n+1), x(1), ..., x(n)--------------------------摘自http://soft.zdnet.com.cn/software_zone/2008/0323/779891.shtml
即
1a
2ab
3abc
..........................
3acb
...........................
3cab
...........................
2ba
3bac
..........................
3bca
..........................
3cba
.........................
//#include <iostream>
#include <cstring>
#include<cstdio>
#include<cstdlib>
#include <string>
#include<algorithm>
#define MARK -2147483647
using namespace std;
char chh[10];
int m;char kongo[10][20]={""," "," "," "," "," "," "," "," " };
int pri[10],pi,left[10],right[10];
void print(int pre,int cc)
{
int i;
int koi;
if(cc==m+1)
{
for(;;){if(left[pre]==0)break;pre=left[pre]; }
printf("%s",kongo[cc-1]);
printf("writeln(");
for(;;)
{ if(left[pre]==0)
printf("%c",(char)(pre+'a'-1));
else printf(",%c",(char)(pre+'a'-1));
if(right[pre]==0)break;
pre=right[pre];
}
printf(")\n");return;
}
for(;;){if(right[pre]==0)break;pre=right[pre]; }
for(;;)
{
if(right[pre]==0)
{ printf("%s",kongo[cc-1]);
printf("if %c < %c then\n",(char)(pre+'a'-1),(char)(cc+'a'-1));
right[pre]=cc;
left[cc]=pre;
print(cc,cc+1);
right[pre]=0;
left[cc]=0;
}
else
{ printf("%s",kongo[cc-1]);
printf("else if %c < %c then\n",(char)(pre+'a'-1),(char)(cc+'a'-1));
left[right[pre]]=cc;
right[cc]=right[pre];
right[pre]=cc;
left[cc]=pre;
print(cc,cc+1);
right[pre]=right[cc];
left[right[cc]]=pre;
left[cc]=0;
right[cc]=0;
}
if(left[pre]==0)
{ printf("%s",kongo[cc-1]);
printf("else\n");
right[cc]=pre;
left[pre]=cc;
print(cc,cc+1);
left[pre]=0;
right[cc]=0;
break;
}
pre=left[pre];
}
return;
}
int main()
{
// freopen("in.txt","r",stdin);
int n;
scanf("%d",&n);int nn=n;
while(n--)
{ if(nn!=n+1)printf("\n");
memset(left,0,sizeof(left));
memset(right,0,sizeof(right));
scanf("%d",&m);
printf("program sort(input,output);\n");
printf("var\n");
char ch='a';
pi=0;
int i;
for(i=0; i<m-1; ++i,++ch)
{
printf("%c,",ch);
chh[i]=ch;
}
printf("%c : integer;\n",ch);
chh[i]=ch;
printf("begin\n");
printf(" readln(");
ch='a';
for(i=0; i<m-1; ++i,++ch)printf("%c,",ch);
printf("%c);\n",ch);
if(m==1)printf(" writeln(a)\n");
else
print(1,2);
printf("end.\n");
}
return 0 ;
}