全排序与康拓展开

全排列:

n=3

123

132

213

231

312

321

(由1~n组成,且出现一次,从小到大排序(或从大到小排序,或不排序))

求全排序:

I.

Dfs1

//全排序没有顺序

#include <iostream>

using namespace std;

long a[100],n;

void swap(long &a,long &b)

{

long temp;

temp=a;

a=b;

b=temp;

}

void dfs(long pos)

{

long i;

if (pos==n)

{

for (i=1;i<=n;i++)

cout<<a[i]<<" ";

cout<<endl;

}

else

{

dfs(pos+1);

for (i=pos+1;i<=n;i++)

{

swap(a[pos],a[i]);  //以a[i]作为第pos位

dfs(pos+1);

swap(a[pos],a[i]);

}

}

}

int main()

{

long i;

cin>>n;

for (i=1;i<=n;i++)

a[i]=i;

dfs(1);

return 0;

}

II.

Dfs2

#include <iostream>

using namespace std;

long n,a[1000];

/*long b[1000],ans,t;*/

bool vis[1000];

void dfs(long pos)

{

long i;

if (pos==n+1)

{

for (i=1;i<=n;i++)

cout<<a[i]<<" ";

cout<<endl;

/*

ans++;

b[ans]=0;

t=1;

for (i=n;i>=1;i--)

{

b[ans]+=t*a[i];

t*=10;

}

*/

}

else

{

for (i=1;i<=n;i++)

if (vis[i])

{

vis[i]=false;

a[pos]=i;

dfs(pos+1);

vis[i]=true;

}

}

}

int main()

{

long i;

cin>>n;

for (i=1;i<=n;i++)

{

vis[i]=true;

a[i]=i;

}

dfs(1);

/*

cout<<endl;

for (i=1;i<=ans;i++)

cout<<b[i]<<endl;

cout<<endl;

for (i=1;i<ans;i++)

cout<<b[i+1]<<" - "<<b[i]<<" = "<<b[i+1]-b[i]<<endl;

*/

return 0;

}

III.

从小到大排序,由第k个数推出第(k+1)个数

#include <iostream>

#include <sys/timeb.h>

using namespace std;

int main()

{

long n;

cin>>n;

struct timeb t1,t2;

ftime(&t1);

long a[100],i,j,temp,x,y;

for (i=1;i<=n;i++)

a[i]=i;

i=n-1;

while (i)

{

for (j=1;j<=n;j++)

cout<<a[j]<<" ";

cout<<endl;

//126543    -->132456

//136542    -->142356

//146532    -->152346

for (j=n;j>=1;j--)

if (a[j]>a[i])

break;

temp=a[i];

a[i]=a[j];

a[j]=temp;

//i+1~n

x=i+1;

y=n;

while (x<y)

{

temp=a[x];

a[x]=a[y];

a[y]=temp;

x++;

y--;

}

for (i=n-1;i>0;i--)

if (a[i]<a[i+1])

break;

}

for (j=1;j<=n;j++)

cout<<a[j]<<" ";

cout<<endl;

ftime(&t2);

cout<<(t2.time-t1.time)+(t2.millitm-t1.millitm)/1000.0<<endl;

return 0;

}

IV.

康拓展开,通过数的编号逆推出数

#include <iostream>

using namespace std;

int main()

{

long n,value[15],i,j,k,s,num;

bool vis[15];

cin>>n;

value[0]=0;

value[1]=1;

for (i=2;i<=n;i++)

value[i]=value[i-1]*i;

for (i=0;i<value[n];i++)

{

for (j=1;j<=n;j++)

vis[j]=false;

s=i;

for (j=n-1;j>=0;j--)

{

num=s/value[j];

s-=num*value[j];

k=1;

while (vis[k])

k++;

while (num)

{

num--;

k++;

while (vis[k])

k++;

}

vis[k]=true;

cout<<k<<" ";

}

cout<<endl;

}

return 0;

}

康拓展开

s[1],s[2],…,s[n]都不相同,且{s[1],s[2],…,s[n]}={1,2,…,n}

   X=(s[1],s[2],…,s[n])

Number(X)=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[1]*0!

a[i]:数s[i]比s[i+1]~s[n]大的个数或者s[i]-1 减去s[i]比s[1]~s[i-1]大的数目

(因为n个数从1~n且都不相同,比s[i]小的数有s[i]-1个)

如X=2413

Number(2413)=1*3!+2*2!+0*1!+0*0!=10

求一个数X的编号

Code:

#include <iostream>

using namespace std;

int main()

{

long n,i,j,s[11],value[11],g,ans=0;

cin>>n;

for (i=1;i<=n;i++)

cin>>s[i];

value[0]=0;

value[1]=1;

for (i=2;i<n;i++)

value[i]=value[i-1]*i;

for (i=1;i<=n;i++)

{

g=0;

for (j=i+1;j<=n;j++)

if (s[i]>s[j])

g++;

/*

g=s[i]-1;

for (j=1;j<i;j++)

if (s[i]>s[j])

g--;

*/

ans+=g*value[n-i];

}

cout<<ans<<endl;

return 0;

}

Code:(高精度)

#include <iostream>

#include <memory.h>

using namespace std;

long max(long a,long b)

{

if (a>b)

return a;

else

return b;

}

int main()

{

long n,i,j,s[100],value[100][100],len[100],g,ans[100],lenans,c[100],lenc;

cin>>n;

for (i=1;i<=n;i++)

cin>>s[i];

value[0][1]=0;

len[1]=1;

value[1][1]=1;

len[1]=1;

for (j=2;j<n;j++)

{

value[j][1]=0;

for (i=1;i<=len[j-1];i++)

{

value[j][i]+=value[j-1][i]*j;

if (value[j][i]>=10000)

{

value[j][i+1]=value[j][i]/10000;

value[j][i]=value[j][i]%10000;

}

else

value[j][i+1]=0;

}

if (value[j][i]==0)

len[j]=len[j-1];

else

len[j]=len[j-1]+1;

}

/*

value[0]=0;

value[1]=1;

for (i=2;i<n;i++)

value[i]=value[i-1]*i;

*/

lenans=1;

memset(ans,0,sizeof(ans));

for (i=1;i<=n;i++)

{

g=0;

for (j=i+1;j<=n;j++)

if (s[i]>s[j])

g++;

//ans+=g*value[n-i];

c[1]=0;

for (j=1;j<=len[n-i];j++)

{

c[j]+=g*value[n-i][j];

if (c[j]>=10000)

{

c[j+1]=c[j]/10000;

c[j]=c[j]%10000;

}

else

c[j+1]=0;

}

if (c[j]==0)

lenc=j-1;

else

lenc=j;

lenans=max(lenans,lenc);

for (j=1;j<=lenans;j++)

{

ans[j]+=c[j];

if (ans[j]>=10000)

{

ans[j+1]++;

ans[j]-=10000;

}

}

if (ans[j]!=0)

lenans++;

}

//cout<<ans<<endl;

cout<<ans[lenans];

for (i=lenans-1;i>=1;i--)

if (ans[i]>=1000)

cout<<ans[i];

else if (ans[i]>=100)

cout<<"0"<<ans[i];

else if (ans[i]>=10)

cout<<"00"<<ans[i];

else

cout<<"000"<<ans[i];

cout<<endl;

return 0;

}

Input:

100

100 99 98 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62 61

60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21

20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

Output:

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916863999999999999999999999999

时间: 2024-10-06 09:05:48

全排序与康拓展开的相关文章

五 数据组织模式 4)全排序、混排。

前面讲的 分区.分箱模式 都是不关心数据的顺序. 接下来 全排序.混排序模式 关心的是数据按照指定键进行并行排序. 全排序解释: 排序在顺序结构程序中容易实现, 但是在MapReduce 中,或者说在并行编程中不易实现.这是典型的 "分治法". 每个 reduce 将按照键对他的数据排序,但这种排序并不是全局意义上的排序. 这里想做的是全排序,记录是整个数据集按照顺序排列好的. 作用: 排序号的数据有很多有用的特性,比如时间排序可以提供一个基于时间轴的视图.在一个已排序好的数据集中查找

康拓展开与逆康拓展开

1.康托展开的解释 康托展开就是一种特殊的哈希函数 把一个整数X展开成如下形式: X=a[n]*n!+a[n-1]*(n-1)!+...+a[2]*2!+a[1]*1! 其中,a为整数,并且0<=a<i,i=1,2,..,n {1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按从小到大排列一共6个.123 132 213 231 312 321 . 代表的数字 1 2 3 4 5 6 也就是把10进制数与一个排列对应起来. 他们间的对应关系可由康托展开来找到.

九宫重拍(bfs + 康拓展开)

问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12345678. 把第二个图的局面记为:123.46758 显然是按从上到下,从左到右的顺序记录数字,空格记为句点. 本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达.如果无论多少步都无法到达,则输出-1. 输入格式 输入第一行包含九宫的初态,第二行包含九宫的终态. 输出格式 输出最

ACM/ICPC 之 BFS(离线)+康拓展开 (HDU1430-魔板)

魔板问题,一道经典的康拓展开+BFS问题,为了实现方便,我用string类来表示字符串,此前很少用string类(因为不够高效,而且相对来说我对char数组的相关函数比较熟),所以在这里也发现了很多容易被忽视的问题. 对于康拓展开不太熟系的可以先参看一篇博客:http://blog.csdn.net/zhongkeli/article/details/6966805 关于sting类,大家要注意,在赋值的时候,其赋值位置不能与首位置间存在未赋值部分. 题目需要转换思路的地方是: 我们需要将起始魔

Hdoj 1430 魔板 【BFS】+【康拓展开】+【预处理】

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2139    Accepted Submission(s): 452 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

九宫重排_康拓展开_bfs

历届试题 九宫重排 时间限制:1.0s   内存限制:256.0MB 问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12345678. 把第二个图的局面记为:123.46758 显然是按从上到下,从左到右的顺序记录数字,空格记为句点. 本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达.如果无论多少步都无法到达,则输出-1. 输入格

M/R全排序

例如:1KW数据,200个map,100个reduce. (1)map阶段,每个map分别局部排序,得到200个排好顺序的结果 (2)对所有的数据进行99个抽样s1,s2...s99(按照顺序排列) (3)根据每个map中数据在抽样数据的前后,将每个map划分成(最多)100个部分m1-1,m1-2....m1-100,m2-1,m2-2...m2-100...m200-1,m200-2,m200-100,所有map(最多)2W个部分 (4)这2W个部分每个部分按照抽样和抽样的比较分别放在每个抽

hive全排序

全排序 hive的排序关键字是SORT BY,它有意区别于传统数据库的ORDER BY也是为了强调两者的区别–SORT BY只能在单机范围内排序. 1.1.1     例1 set mapred.reduce.tasks=2; 原值 select cookie_id,page_id,id fromc02_clickstat_fatdt1 where cookie_idIN('1.193.131.218.1288611279693.0','1.193.148.164.1288609861509.2

全排序之字典排序

字典序全排列算法研究 一. 非递归算法(字典序法) 对给定的字符集中的字符规定了一个先后关系,在此基础上规定两个全排列的先后是从左到右逐个比较对应的字符的先后. 例如:字符集{1,2,3},较小的数字位置较先,这样按字典序生成的全排列是 123,132,213,231,312,321 ※ 一个全排列可看做一个字符串,字符串可有前缀.后缀. 生成给定全排列的下一个排列.所谓一个的下一个就是这一个与下一个之间没有其他的.这就要求这一个与下一个有尽可能长的共同前缀,也即变化限制在尽可能短的后缀上. 对